Skip to content

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:

My Experience
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:

Reddit Comment
"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.md
is the intake point, not the permanent home."

Another user confirmed:

Reddit Comment
"The claude.md bloat cycle is painfully real. Mine went through the exact
same pattern -- starts lean, accumulates edge cases, becomes a wall of text
the 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:

Reddit Comment (Score 8)
"Once mine hit 150 lines, the agent started deprioritizing sections near the
end -- not ignoring them outright, just weighting them lower when anything
near 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:

Reddit Comment (Score 2)
"What's worked for me is splitting it into a hierarchy rather than one
monolithic file. I keep a short root CLAUDE.md with core principles and
import 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)

CLAUDE.md (BEFORE)
# Project Configuration
## Build Commands
npm run build - Production build
npm run dev - Development server
npm test - Run tests
npm run lint - Check code quality
npm run format - Format code
npm run typecheck - Type checking
npm run deploy - Deploy to staging
npm 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

CLAUDE.md (AFTER)
# Project Configuration
## Quick Start
npm 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 workflow

New file: .claude/rules/coding-style.md

.claude/rules/coding-style.md
# Coding Style
## Immutability
ALWAYS 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 Handling
ALWAYS 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

.claude/rules/testing.md
# Testing Requirements
## Minimum Test Coverage: 80%
Test Types (ALL required):
1. **Unit Tests** - Individual functions, utilities, components
2. **Integration Tests** - API endpoints, database operations
3. **E2E Tests** - Critical user flows (Playwright)
## Test-Driven Development
MANDATORY workflow:
1. Write test first (RED)
2. Run test - it should FAIL
3. Write minimal implementation (GREEN)
4. Run test - it should PASS
5. Refactor (IMPROVE)
6. Verify coverage (80%+)

New file: .claude/rules/git-workflow.md

.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 changes
3. Draft comprehensive PR summary
4. Include test plan with TODOs
5. Push with `-u` flag if new branch

The 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 Directory Structure
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:

  1. CLAUDE.md always loads (keep it lean)
  2. rules/ files load when their domain is relevant
  3. 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.

The Bloat Pattern
# 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 lines

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

Wasteful vs Useful
# 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 components

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

Verbose vs Concise
# BAD: Verbose
When you are creating a new component, you should make sure to create a new
file for it. The file should be placed in the appropriate directory based on
its type. Components should be organized by feature rather than by type...
# GOOD: Concise
- One component per file
- Organize by feature/domain, not by type

Mistake 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