CLAUDE.md Mastery: Writing Project Instructions That Claude Actually Follows

Beginner8m readFull-stack developers

CLAUDE.md Mastery: Writing Project Instructions That Claude Actually Follows Every Claude Code session loads a single CLAUDE.md file into the context window.

Primary Focus

ai development

AI Tools Covered

AI-firstNext.jsConvex

What You'll Learn

  • The Three Failure Modes
  • Specific > General
  • The Verification Command Pattern
  • Patterns 1–3: Negative Examples, Absolute Constraints, and Path-Scoped Rules
  • Patterns 4–7: Enforcement Gates, Dependency Chains, Escape Hatches, Living Updates
  • The Cost of Bloat and How to Fix It

Guide Curriculum

Why Most CLAUDE.md Files Don't Work

Learn key concepts

3 lessons
  • The Three Failure Modes10m
  • Specific > General10m
  • The Verification Command Pattern10m

The 7 Patterns That Make Instructions Stick

Learn key concepts

2 lessons
  • Patterns 1–3: Negative Examples, Absolute Constraints, and Path-Scoped Rules10m
  • Patterns 4–7: Enforcement Gates, Dependency Chains, Escape Hatches, Living Updates10m

Maintaining CLAUDE.md Over Time: Bloat, Drift, and Pruning

Learn key concepts

5 lessons
  • The Cost of Bloat and How to Fix It10m
  • Structure for Scanning10m
  • Adding New Fields10m
  • Deleting Fields10m
  • Pruning Without Losing Context10m

Preview: First Lesson

Why Most CLAUDE.md Files Don't Work

The Three Failure Modes

Why Most CLAUDE.md Files Don't Work

The most common CLAUDE.md mistakes fall into three categories: vagueness, breadth, and aspirational-only content.

Vagueness sounds like: "Always be careful when modifying the database." Claude will nod along, but what does "careful" mean? Don't modify production? Don't drop tables? Don't change schemas? Vague rules create uncertainty, and Claude errs on the side of asking for permission rather than acting confidently.

Breadth is when you dump everything you wish Claude knew into CLAUDE.md. "Here's our testing philosophy, our git workflow, our deployment procedure, our code style, our API design patterns..." This creates a 50KB wall of text that gets truncated or ignored.

Aspirational-only content is the biggest trap. Rules like "Always write unit tests for new functions" sound good, but they don't include the verification command. How does Claude know if the rule was followed? Without a self-check mechanism, Claude will write the tests, then forget they exist and move on.

The fix is specificity, scoping, and verification.

Free Access

Start learning with this comprehensive guide

This guide includes:

3 modules with 10 lessons
8m estimated reading time

About the Author

H
✨ Vibe Coder
@hiram-clark

Hiram Clark is the founder and managing editor of vybecoding.ai and sets editorial direction for the guides and news published here. Articles are drafted with AI assistance and edited before publication. He works hands-on with the AI development tools, workflows, and infrastructure covered on the site.

Full Guide Content

Complete lesson text — start the interactive course above for exercises and progress tracking.

Module 1Why Most CLAUDE.md Files Don't Work

1.1The Three Failure Modes

Why Most CLAUDE.md Files Don't Work

The most common CLAUDE.md mistakes fall into three categories: vagueness, breadth, and aspirational-only content.

Vagueness sounds like: "Always be careful when modifying the database." Claude will nod along, but what does "careful" mean? Don't modify production? Don't drop tables? Don't change schemas? Vague rules create uncertainty, and Claude errs on the side of asking for permission rather than acting confidently. Breadth is when you dump everything you wish Claude knew into CLAUDE.md. "Here's our testing philosophy, our git workflow, our deployment procedure, our code style, our API design patterns..." This creates a 50KB wall of text that gets truncated or ignored. Aspirational-only content is the biggest trap. Rules like "Always write unit tests for new functions" sound good, but they don't include the verification command. How does Claude know if the rule was followed? Without a self-check mechanism, Claude will write the tests, then forget they exist and move on.

The fix is specificity, scoping, and verification.

1.2Specific > General

Replace every generic rule with a concrete command or constraint.

Bad: "Be mindful of database performance." Good: "Before running migrations on the prod database, use npx convex run verifyMigration --prod to check for full-table scans." Bad: "Follow the project's code style." Good: "Use the ESLint config in .eslintrc.json. Run npm run lint:fix before committing." Bad: "Test your changes." Good: "Run npm test -- --coverage and ensure coverage is ≥85%. Commit only if all tests pass."

Specific rules are verifiable. Vague rules are not.

1.3The Verification Command Pattern

Every rule should have a built-in self-check. This is how Claude confirms compliance without asking you.

Example:

## Database Migrations

When modifying the schema:
1. Create a migration file in convex/schema.ts
2. Run: npx convex run verifyMigration --dev
3. Check the output for warnings. Do not proceed if you see "FULL_TABLE_SCAN"
4. Test locally: npm test
5. Verification: npm run schema:validate (should output "✓ Schema valid")

The npm run schema:validate command is your verification gate. Claude can run it, see the output, and know whether the rule was followed.

Without this, Claude might write the code and trust that it works. With verification, Claude knows.


Module 2The 7 Patterns That Make Instructions Stick

2.1Patterns 1–3: Negative Examples, Absolute Constraints, and Path-Scoped Rules

The 7 Patterns That Make Instructions Stick

Pattern 1: Negative Examples are more powerful than positive ones.
## DO NOT delete database records via direct mutation
❌ WRONG:
  db.patch(docId, { deleted: true }) // silent corruption

✓ RIGHT:
  await ctx.db.patch(docId, { isDeleted: true, deletedAt: Date.now() })
  // soft delete with timestamp

Negative examples stick because Claude sees the failure case first.

Pattern 2: Absolute Constraints prevent entire categories of mistakes.
## Convex Production Database
- NEVER use --prod flag unless explicitly instructed
- NEVER run destructive commands (delete, patch batch) without --dry-run first
- ALWAYS verify output before applying changes

Absolute rules are black-and-white. No gray area, no interpretation needed.

Pattern 3: Path-Scoped Rules avoid applying all rules to all files.
## Rules for convex/schema.ts
When modifying convex/schema.ts:
- Never add a required field to an existing table without a default value
- Run: npx convex codegen after any schema change
- Verification: git diff should show no breaking changes

## Rules for src/components/
- Use React hooks, not class components
- Every component ≥200 LOC must have TypeScript types
- Verification: npm run type-check should pass

This keeps rules focused. Rules for the database schema don't clutter rules for React components.

2.2Patterns 4–7: Enforcement Gates, Dependency Chains, Escape Hatches, Living Updates

Pattern 4: Enforcement Gates are commands that must pass before proceeding.
## Before committing:
1. npm run lint:fix (must pass)
2. npm test (must pass with coverage ≥80%)
3. npm run type-check (must pass)
ONLY commit after all three gates pass.

Claude will follow this sequentially because it's a clear chain.

Pattern 5: Dependency Chains tell Claude the order of operations.
## Creating a new feature:
1. Update convex/schema.ts with new tables/fields
2. Run: npx convex codegen (depends on step 1)
3. Create API function in convex/myfeature.ts (depends on step 2)
4. Create React hook in src/hooks/useMyFeature.ts (depends on step 3)
5. Create component in src/components/MyFeature.tsx (depends on step 4)
6. Test in src/__tests__/MyFeature.test.tsx (depends on step 5)

Each step depends on the previous one — this isn't arbitrary.

Pattern 6: Escape Hatches acknowledge that rules will sometimes need to be broken.
## DO NOT modify production data

EXCEPTION: If you have explicit permission from the on-call engineer, 
use convex run --prod --dry-run first, show output, wait for approval.

This prevents Claude from getting stuck when rules conflict with real-world needs.

Pattern 7: Living Updates means CLAUDE.md changes as your project evolves.

Every sprint, review CLAUDE.md: remove rules that no longer apply, add rules for new failure modes, update verification commands as your CI/CD pipeline changes. Old CLAUDE.md files are worse than no CLAUDE.md because Claude follows outdated rules.


Module 3Maintaining CLAUDE.md Over Time: Bloat, Drift, and Pruning

3.1The Cost of Bloat and How to Fix It

Maintaining CLAUDE.md Over Time

CLAUDE.md is loaded into every context window. If it's 10KB, that's ~2,500 tokens. If it's 50KB, that's ~12,500 tokens. You're paying that cost on every single conversation.

Bloat sources:
  • Aspirational content ("Here's our dream architecture...")
  • Outdated rules from 6 months ago
  • Overly detailed philosophy paragraphs
  • Duplicate rules in different sections
  • Rules that duplicate project documentation
Audit checklist:
  • Is this rule referenced in the codebase (via comments or convention)?
  • Does this rule prevent a real failure mode Claude has hit before?
  • Could this rule live in project docs instead?
  • Is this rule still true today?

If you answer "no" to any of these, consider removing it.

3.2Structure for Scanning

Claude scans CLAUDE.md quickly. Structure it for skim-reading, not deep study.

Use:

  • Clear headings (## Section, ### Category)
  • Bullet points for lists
  • Code blocks for commands
  • Bolded key terms

Avoid:

  • Long paragraphs without headings
  • Narrative prose (save that for your project wiki)
  • Rules buried in explanatory text
Good structure example:

```

Convex Database

3.3Adding New Fields

  • Never add required fields without defaults
  • Command: npx convex codegen
  • Verification: npm run type-check

3.4Deleting Fields

  • Never delete in place; use soft-delete pattern
  • Add _isDeleted: Boolean, _deletedAt: Number fields
  • Command: npx convex run migrateData

```

3.5Pruning Without Losing Context

Once a quarter:

  1. List all rules in CLAUDE.md
  2. Check git history: how often was each rule relevant?
  3. Ask: "If we removed this rule, would Claude break the project?"
  4. If the answer is "probably not," move it to project docs or remove it
What to move to project docs:
  • Architecture overview (too large for CLAUDE.md)
  • Historical context ("We used to do X, now we do Y")
  • Philosophy and rationale (useful for onboarding, not daily work)
What to keep in CLAUDE.md:
  • Immediate constraints and failure modes
  • Verification commands
  • "Never do this" rules
  • Path-scoped guardrails
Final test: Can a new developer read CLAUDE.md in 5 minutes and feel confident making code changes? If not, it's too bloated.