Why CLAUDE.md Compliance Degrades Past 100 Lines (And How to Fix It)
Problem
My CLAUDE.md file was 180 lines long and Claude was ignoring half of it.
I had carefully documented every project convention, coding standard, and workflow rule. But when I asked Claude to follow the rules at the bottom of the file, it would either miss them completely or apply them inconsistently.
Here’s what happened:
Me: "Follow the error handling conventions in CLAUDE.md"Claude: *applies conventions from the top, ignores the error handling section*
Me: "Check line 150 of CLAUDE.md for the security checklist"Claude: *runs a generic security scan, misses project-specific checks*
Me: "Why didn't you follow the commit message format?"Claude: "I apologize, I'll follow it now." *still uses generic format*The pattern was clear: rules near the top worked fine. Rules near the bottom were ignored or deprioritized. This wasn’t random inconsistency—it was position-dependent reliability degradation.
What Happened?
I found a Reddit thread titled “From Zero to Fleet: The Claude Code Progression Ladder” that explained exactly what I was experiencing.
The top comment described my situation perfectly:
"Compliance degrades past ~100 lines. I bloated mine to 145, trimmed to 80,watched it creep back to 190, ran an audit, found 40% redundancy. CLAUDE.mdis the intake point, not the permanent home."Another user confirmed:
"The claude.md bloat cycle is painfully real. Mine went through the exactsame pattern -- starts lean, accumulates edge cases, becomes a wall of textthe agent half-ignores."The key insight: LLMs weight content at the beginning of context more heavily than content near the end. This is called “position bias” and it’s a fundamental limitation of transformer architectures.
One comment explained the mechanism:
"Once mine hit 150 lines, the agent started deprioritizing sections near theend -- not ignoring them outright, just weighting them lower when anythingnear the top conflicted."This matched my experience exactly. Claude wasn’t ignoring my rules—it was applying a gradient of attention that favored the top of the file.
Why This Happens
Position bias exists in all transformer-based LLMs. Here’s why:
Attention mechanism limitations: Transformers use attention mechanisms to weigh the importance of different tokens. Early tokens influence how later tokens are interpreted, creating an inherent bias toward the beginning of the context.
Limited focus capacity: Attention mechanisms have finite capacity to maintain equal focus across long sequences. As context grows, the model must distribute attention, and earlier content often receives stronger weights.
Conflict resolution: When instructions conflict, models tend to favor earlier, more strongly-weighted content. If your CLAUDE.md says “write tests” at line 10 and “skip tests for prototypes” at line 150, Claude will write tests for everything—even prototypes.
The observable symptoms in my workflow:
- Instructions near the end got “deprioritized” (not ignored, just weighted lower)
- Edge-case rules added later conflicted with earlier principles
- The “bloat cycle”: starts lean, accumulates edge cases, becomes unreliable
The Solution: Progressive Disclosure Architecture
Claude Code implements a three-level loading system designed to manage this limitation:
Level 1: Always-Loaded Metadata (~100 words)
- Skill name and description
- Critical, always-relevant instructions
- Target: Under 100 lines in CLAUDE.md
Level 2: Triggered Body (<5k words)
- Loaded only when the skill is invoked
- Workflow instructions and procedural guidance
- Stored in SKILL.md body
Level 3: On-Demand References (unlimited)
- Loaded only when Claude decides it’s needed
- Domain-specific schemas, examples, detailed guides
- Stored in
references/subdirectory
The Reddit thread confirmed this approach works:
"What's worked for me is splitting it into a hierarchy rather than onemonolithic file. I keep a short root CLAUDE.md with core principles andimport references to focused sub-docs for specific domains."How I Fixed It
I restructured my project configuration from a single bloated file to a progressive disclosure architecture:
Before: Bloated CLAUDE.md (180 lines)
# Project Configuration
## Build Commandsnpm run build - Production buildnpm run dev - Development servernpm test - Run testsnpm run lint - Check code qualitynpm run format - Format codenpm run typecheck - Type checkingnpm run deploy - Deploy to stagingnpm run deploy:prod - Deploy to production
## Testing Requirements- Minimum Test Coverage: 80%- ALL tests must pass before commit- Unit tests for utilities- Integration tests for API endpoints- E2E tests for critical user flows- Test-driven development workflow- Use **tdd-guide** agent for new features- Run tests after every change- Check coverage reports weekly
## Code Style- ALWAYS create new objects, NEVER mutate- 200-400 lines typical, 800 max- Extract utilities from large components- Organize by feature/domain, not by type- Use Repository pattern for data access- All API responses use `{ data, error, meta }` shape- Use functional components with hooks- No console.log in production- Prefer composition over inheritance
## Git Workflow- Commit message format: `<type>: <description>`- Types: feat, fix, refactor, docs, test, chore, perf, ci- Create feature branches for new work- PRs require at least one approval- Run linter before commit- Run tests before push
...continues for 150+ lines with every possible instruction...This file had everything. And that was the problem.
After: Lean CLAUDE.md (60 lines) + Rules
# Project Configuration
## Quick Startnpm run dev
## Architecture- Frontend: React + TypeScript- Backend: Node.js + Express- Database: PostgreSQL
## Key Patterns- Use Repository pattern for data access- All API responses use `{ data, error, meta }` shape- See .claude/rules/ for detailed conventions
## Testing- Minimum coverage: 80%- See .claude/rules/testing.md for workflowNew file: .claude/rules/coding-style.md
# Coding Style
## ImmutabilityALWAYS create new objects, NEVER mutate:
function updateUser(user, name) { return { ...user, name }}
## File Organization- 200-400 lines typical, 800 max- Extract utilities from large components- Organize by feature/domain, not by type
## Error HandlingALWAYS handle errors comprehensively:
try { const result = await riskyOperation() return result} catch (error) { console.error('Operation failed:', error) throw new Error('Detailed user-friendly message')}New file: .claude/rules/testing.md
# Testing Requirements
## Minimum Test Coverage: 80%
Test Types (ALL required):1. **Unit Tests** - Individual functions, utilities, components2. **Integration Tests** - API endpoints, database operations3. **E2E Tests** - Critical user flows (Playwright)
## Test-Driven Development
MANDATORY workflow:1. Write test first (RED)2. Run test - it should FAIL3. Write minimal implementation (GREEN)4. Run test - it should PASS5. Refactor (IMPROVE)6. Verify coverage (80%+)New file: .claude/rules/git-workflow.md
# Git Workflow
## Commit Message Format
`<type>: <description>`
Types: feat, fix, refactor, docs, test, chore, perf, ci
## Pull Request Workflow
When creating PRs:1. Analyze full commit history (not just latest commit)2. Use `git diff [base-branch]...HEAD` to see all changes3. Draft comprehensive PR summary4. Include test plan with TODOs5. Push with `-u` flag if new branchThe difference is dramatic. The main CLAUDE.md file is now 60 lines—well under the 100-line threshold where position bias becomes problematic. Detailed rules are demand-loaded only when relevant.
Directory Structure
The final structure looks like this:
project/├── CLAUDE.md (50-80 lines: core principles, architecture, quick commands)└── .claude/ ├── rules/ │ ├── coding-style.md (immutable patterns) │ ├── testing.md (test conventions) │ ├── git-workflow.md (commit/PR conventions) │ └── security.md (security checklist) └── skills/ ├── project-conventions/SKILL.md (background knowledge) └── api-patterns/SKILL.md (domain-specific guidance)Claude Code loads these files progressively:
- CLAUDE.md always loads (keep it lean)
- rules/ files load when their domain is relevant
- skills/ files load when explicitly invoked
Why This Matters
Context window economics: Every line in CLAUDE.md consumes tokens that could be used for actual work. The last 20% of context window is particularly unreliable for complex tasks.
Redundancy audit: The Reddit poster found 40% redundancy in their bloated CLAUDE.md. I audited mine and found similar duplication—same instructions written slightly differently in multiple places.
The “intake point” framing: CLAUDE.md should capture learnings during a session. After capture, move stable patterns to skills/rules. Keep CLAUDE.md lean as a discovery and navigation layer.
Common Mistakes
I made several mistakes while learning this:
Mistake 1: Adding without removing
Each new edge case got appended. No periodic audits to move stable patterns. Result: gradual bloat and degradation.
# Session 1: CLAUDE.md is 40 lines# Session 5: Added error handling rules, now 60 lines# Session 10: Added security checklist, now 85 lines# Session 15: Added API conventions, now 120 lines# Session 20: Compliance degrades, now 150 linesMistake 2: Generic best practices
“Always write tests” is not project-specific. Claude already knows this—it wastes context. Only include non-obvious, project-specific patterns.
# WASTES CONTEXT- Always write tests- Use meaningful variable names- Handle errors properly
# PROJECT-SPECIFIC (useful)- Test coverage minimum: 80% (enforced in CI)- All API responses use `{ data, error, meta }` shape- Never mutate state in React componentsMistake 3: Verbose explanations
Long explanations that restate obvious code. One-liners are better than paragraphs. Trust Claude to understand—focus on what it doesn’t know.
# BAD: VerboseWhen you are creating a new component, you should make sure to create a newfile for it. The file should be placed in the appropriate directory based onits type. Components should be organized by feature rather than by type...
# GOOD: Concise- One component per file- Organize by feature/domain, not by typeMistake 4: Duplicating across files
Same instruction in CLAUDE.md and a skill file. Claude sees redundancy and may weight both lower. Each piece of information should have one canonical home.
Results After Restructuring
After moving my CLAUDE.md to a progressive disclosure architecture:
- File reduced from 180 lines to 60 lines
- Compliance with rules improved significantly
- Claude started applying rules from .claude/rules/ correctly
- No more position-dependent reliability issues
The key metric: I stopped seeing Claude ignore instructions near the bottom of the file. All rules, regardless of their location in the hierarchy, get appropriate attention when their domain is relevant.
Summary
In this post, I explained why CLAUDE.md compliance degrades past ~100 lines due to fundamental LLM position bias. The solution is progressive disclosure: keep CLAUDE.md under 100 lines as a navigation layer and move stable conventions to demand-loaded skill files.
The fix isn’t about writing better instructions—it’s about putting instructions in the right place. CLAUDE.md is the intake point, not the permanent home. Audit your CLAUDE.md today: what can move to .claude/rules/ or .claude/skills/?
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments