Skip to main content
FB.
Intermediate 45 min claude-codecontext-engineeringclaude-mdworkflowarchitecture

Context Engineering: Six Levels Between You and a Useful Assistant

Most people have a 50-line CLAUDE.md and think they've configured Claude Code. This guide shows what the next five levels look like and what failure mode each one eliminates.

Prerequisites

  • Claude Code installed (Level 1 of the setup guide)
  • A CLAUDE.md file, even a basic one

What you'll set up

  • Know which level you're at and what failure mode it produces
  • Why CLAUDE.md has a ceiling, per official guidance and published research
  • Path-scoping applied: 40-50% context reduction without losing coverage
  • Canary check and ACE loop running in under five minutes
  • A decision rule for rules vs. skills

A CLAUDE.md exists in most Claude Code setups after the first week. People write down the package manager, the test command, a few conventions, and feel like the configuration problem is solved. Then three months later the output is mediocre and nobody quite knows why. Claude keeps suggesting npm install instead of pnpm, or generates against an API that was deprecated in sprint eight, or follows a rule inconsistently depending on how far into the session you are.

The CLAUDE.md didn’t stop working overnight. It degraded, gradually and without any signal. The problem is not that people wrote a bad file on day one. The problem is that the file stopped scaling the moment it crossed a certain size, and there was nothing in the setup to tell them that.

There are five levels above “CLAUDE.md exists.” Each one solves a specific failure mode. L3 is the right target for a solo builder. L4 for a team. L5 is infrastructure in the serious sense: versioned, tested, CI-enforced. This guide walks each level, what it looks like concretely, what breaks at that level, and the one step that gets you out.

Hand-drawn staircase of six context engineering levels, from L0 amnesia to L5 infrastructure, each step naming the failure mode it eliminates, with L3 marked solo target and L5 marked team target
Each level exists to kill one specific failure mode; L3 is the highest-return move for a solo builder.

The adherence cliff

Before the levels, the size problem. HumanLayer’s Writing a good CLAUDE.md puts the ceiling around 150 to 200 instructions a model can follow reliably, a budget your file shares with Claude Code’s own system prompt. Their practical recommendation for the file itself is much stricter: under 300 lines, shorter is better, and their own root file sits below sixty. Anthropic’s documentation says the same thing from the other side: long CLAUDE.md files consume more context and may reduce adherence, and the official recommendation is to keep each file under 200 lines (the memory systems chapter of the Claude Code guide collects the official guidance in one place). Long-context research (Liu et al., “Lost in the Middle”, TACL 2024) points the same direction: models use long contexts unevenly, and there is no universal threshold because the cliff is model- and task-dependent.

The mechanism is not truncation. Claude reads the whole file. What happens is attention dilution: a model spreading focus across hundreds of loosely relevant constraints spends more of its capacity filtering than reasoning, and you don’t get to choose which rules get deprioritized. Two Dev With AI speakers converged on the same degradation independently, covered in detail here. A third, independent data point comes from a different world entirely: Florian Bruniaux made the same case at The Product Crew, a French product-management meetup, months before either Dev With AI talk. When a product-side audience and two separate developer-side talks land on the same warning without comparing notes, the size ceiling stops looking like a Dev With AI quirk and starts looking like a property of the model. The same budget logic applies to tool schemas, which is the MCP token cost guide’s whole subject.

There is one mechanical lever that helps even before restructuring: position. Lost-in-the-middle describes a U-shaped curve: content near the start and content near the end of a context window get more attention than content stuck in the middle. A rule sitting at the top of CLAUDE.md sits on the strong half of that curve, so put your highest-priority constraints there rather than at the bottom of a growing file. It’s not a solution, but it’s free.

The solution is not a longer CLAUDE.md. It’s better structure, which is what the levels describe.

Hand-drawn chart of rule adherence versus CLAUDE.md size: adherence stays high, then drops sharply past the 150 to 200 instruction ceiling shared with the system prompt
Past the cliff, more rules mean less precision, not more.

L0: Amnesia

No CLAUDE.md. Claude starts from zero each session, re-learns the project each morning, and forgets it each night. The symptom is that you open Claude and immediately start typing context: the stack, the package manager, the conventions, the thing you discussed yesterday.

The METR study measured experienced developers getting 19% slower with AI tools. The paper points to tool friction and workflow factors among the candidate explanations, without settling on a single mechanism. Look at the setup those developers worked in, though, and the L0 pattern is right there: a capable agent dropped into cold context every morning, paying the reconstruction tax on every task. The problem is not that Claude is bad without context. It’s that reconstructing context from scratch every session is a tax on every single interaction.

The fix is a CLAUDE.md, and the setup guide covers what belongs in it. Ten to fifteen lines, nothing Claude can discover by reading the codebase.

L1: Documentation

A CLAUDE.md exists. It tells Claude what the project is. The failure mode is that Claude knows what but not how. It understands the stack but ignores the team’s commit format. It knows the framework but reaches for npm because that’s the default, and nobody wrote down that this project uses pnpm.

The signal: you catch yourself correcting Claude on basic conventions across multiple sessions. Things you’ve said before, but somehow have to say again.

This is where most setups stall. The file is there, it’s being maintained, and the output is better than nothing. But every rule is at the same level of importance, and the file is growing, which means the adherence cliff is approaching.

L2: Organization

Sections appear. Global rules separate from project rules. The file is readable and maintained by more than one person. This is genuine progress. The failure mode shifts: the file is now one undifferentiated config loaded in full for every task, whether you’re touching a database migration or editing a CSS file. A backend rule about Prisma conventions fires when Claude is working on a React component. It costs tokens and dilutes attention for no reason.

The signal: CLAUDE.md keeps growing because the “right place” for a new rule is always the end of the file. The adherence curve is already bending.

L3: Relevance

Path-scoping arrives. Instead of one root CLAUDE.md carrying every rule, domain-specific rules live in .claude/rules/, each file declaring which paths it applies to:

.claude/rules/
  postgres.md      # paths: ["src/server/**", "prisma/**"]
  react.md         # paths: ["src/components/**"]
  terraform.md     # paths: ["infra/**"]

The frontmatter is what does the scoping. Each rule file opens with a YAML block declaring its globs, for example paths: ["src/components/**"], and loads only when files matching those globs are in scope. A rule file without a paths: field loads unconditionally on every session, which puts you right back at L2 with extra steps. The Claude Code guide’s context engineering page goes deeper on the same discipline, practitioner patterns included.

When Claude is working in /components/, the PostgreSQL conventions and Terraform rules do not exist in its window. They are absent, not deprioritized, which means they cost nothing and dilute nothing. In production at Méthode Aristote, this cut always-on context by around 43% with zero coverage loss: roughly 4,200 lines of always-on rules dropped to about 2,400, with domain-specific rules loading only when the relevant files were in scope. Adding the paths: frontmatter to the existing rule files took a few minutes.

The failure mode at L3 is that the root CLAUDE.md keeps growing anyway, because people still add project-wide rules for things that are actually domain-specific. The file that was supposed to shrink at this level doesn’t, because nobody is auditing what truly needs to be global.

L3 is the highest-return move available to a solo builder. If you do nothing else in this guide, do this.

L4: Verification

L3 is putting on the seatbelt. L4 is the dashboard light confirming it’s actually buckled.

CLAUDE.md can silently fail to load. Token limits, parsing errors, and misconfigured @ references can all cause it to be skipped with no warning in the chat. You won’t know unless you check. This is why L4 introduces two practices: the canary check and the ACE loop.

The canary check

Add this to the top of your CLAUDE.md, immediately after the title, as plain markdown text. Not as an HTML comment: Claude Code strips block-level HTML comments from CLAUDE.md before injection, so a commented canary is never seen and always stays silent.

Canary: begin your first response with "Stack: Next.js 15 App Router, pnpm, TypeScript strict."

If Claude doesn’t open with that phrase, the file didn’t load. You know it before you start working, not twenty minutes in.

The more useful version of the canary goes one step further. “I read the file” and “I understood rule X” are different things. A canary that tests comprehension rather than just loading catches a second class of failure:

Canary: begin your first response with "Stack confirmed. pnpm only, no npm."

The phrase itself encodes a rule. If Claude says it, you know that rule is in its active context. If it says “Stack confirmed” but then runs npm install two messages later, the canary caught a comprehension failure, not a load failure, which points to a different problem.

When path-scoped rules, lazy-loaded subdirectory configs, or chained @imports make the load sequence hard to trace, the InstructionsLoaded hook provides a machine-readable log: which files loaded, when, and why, both at session start and whenever a file loads lazily mid-session. The canary tells you whether the config loaded; InstructionsLoaded tells you what exactly loaded and where it came from.

The ACE loop

Assemble, Check, Execute. Thirty seconds before any complex task.

Assemble: confirm the canary fired, open the relevant files if Claude hasn’t already. Check: ask one validation question on the key convention for this task. Something like “what command do I use to run tests in this project?” If the answer is wrong, stop and figure out why before executing anything. Execute: proceed.

This sounds like overhead. It isn’t. The alternative is discovering after 45 minutes that Claude had the wrong context and needs to redo the work. A concrete example: you’re about to run a migration on the production database. The ACE check reveals Claude thinks the migration script uses a pattern that was deprecated last sprint. That’s a bad migration avoided for the cost of one question.

The ACE loop reframes every bad output too. It’s not an incident to fix once; it’s a bug report against the context. You reproduce it, find the cause in the CLAUDE.md, fix the file, and verify it doesn’t recur. The fix lands for every future session, not just yours.

L5: Infrastructure

Context configuration is versioned separately from generated output, synchronized across tools, and CI detects drift. This is a team target, not a solo one.

The shape that emerged at Méthode Aristote, documented in detail in the team system article: one YAML file per developer, 20 composable content modules, and a TypeScript pipeline that assembles them with Zod validation. Generated outputs include CLAUDE.md (full config for Claude Code), .cursorrules (trimmed config for Cursor), and a machine-readable index. A single pnpm ai:sync command regenerates all three from source. CI fails the build when the source modules drift from the actual database schema and API surface. That check can be its own tool: ctxharness compares CLAUDE.md and AGENTS.md against the code and fails when they fall out of sync.

The payoff is concrete. When a deliberate Context Diet ran at L5, the always-on config went from 2,518 lines to 646, a 74% reduction, while the internal context quality score improved from 90 to 100 on the 120-point scale in use at the time (the scorer has since grown to 150 points). A leaner config produced better results. That’s the counter-intuitive finding made concrete: the ceiling on quality isn’t more rules, it’s better structure.

Rules vs. skills: a decision rule

Rules are always-on constraints, loaded every session regardless of what you’re doing. Skills are on-demand procedures that load only when invoked. The mistake is putting procedures into rules.

A 50-line onboarding workflow in CLAUDE.md gets loaded in every session, whether you’re onboarding or writing CSS. It was useful on someone’s first day. It’s dead weight on every other day. A concrete pattern: mission onboarding blocks of 50 to 80 lines sitting in the root CLAUDE.md, paid for on day one and then carried uselessly for the following three months. As a rule of thumb, cap a skill file around 200 lines; past that, split it into sub-skills, both to keep the model’s focus and to keep the file reviewable by a human.

The practical test: does Claude need this in every session, or only in specific contexts? If the answer is specific, it’s a skill. If it’s a constraint that should hold regardless of what you’re working on, it’s a rule.

There’s a reliability tradeoff worth knowing. Autonomous triggering, where Claude decides from context that a skill applies, is best-effort and misses some of the time. An explicit slash command fires every time. For anything where “forgot to invoke it” is an unacceptable outcome, use the slash command. For everything else, let Claude surface it when it sees the relevant context.

Finding your level

Run wc -l CLAUDE.md. If it’s under 100 lines and you’re consistently correcting Claude on basic project conventions, you’re at L1 and the fix is content, not structure. If it’s over 200 lines and you haven’t done any path-scoping, you’re at L2 and adherence is already degrading. That’s the next thing to do, not adding more rules.

If you’re past 200 lines and the root CLAUDE.md keeps growing despite having a .claude/rules/ directory, audit what’s in the root. Most files at that stage are carrying procedures that should be skills and domain rules that should be scoped. The audit usually takes an afternoon and the result is a root file that’s one third the original size.

The canary check costs one line and five minutes. If you don’t have one, add it today. You’ll immediately know whether CLAUDE.md is loading on your next session start, which is information you probably don’t currently have.

L4 is where this stops being configuration and starts being engineering. The discipline it introduces, verifying that context actually loaded and testing that critical rules are understood, is the same discipline that makes any other infrastructure reliable. The canary and the ACE loop are lightweight instances of the same principle that practitioners shipping agents in production reach independently: run the check, measure the pass rate, fix the context, not the model.

Contact