DEV Community

Hamza Syed
Hamza Syed

Posted on Originally published at notvibescoded.com

Context files for coding agents: the complete guide

Every major coding agent now reads a context file at the start of a session. Claude Code reads CLAUDE.md. Cursor reads AGENTS.md and its own rules files. Copilot reads .github/muse-instructions.md. Aider can be pointed at a conventions file. Different names, same idea: a short document that tells the agent how your project works before it touches a line of code.

Context files for coding agents: a guide · NotVibesCoded

Every coding agent reads a context file, CLAUDE.md, AGENTS.md, Copilot instructions, and most of them are decoration. The complete guide to writing one that…

favicon notvibescoded.com

Most of these files are useless. They’re either empty, a wishlist (“write clean, maintainable code”), or a 500-line brain dump nobody maintains. The agents aren’t the problem. The files are. This guide is the merged, field-tested version of everything we’ve published on the topic: what to put in the file, what to leave out, how to structure it, and how to prompt in a way that makes the file pay off.

One file, several names: don’t maintain five copies

If you use more than one agent (most developers now do), the naming sprawl becomes its own problem: CLAUDE.md for Claude Code, AGENTS.md as the cross-tool standard Cursor and others read, .github/muse-instructions.md for Copilot, a conventions file for Aider. Five copies of the same rules will drift apart, and drifted instructions are worse than missing ones, because each agent then follows a different version of your conventions.

The setup that survives: one canonical file, thin pointers everywhere else. Keep the real content in AGENTS.md (the name the most tools read natively), and make each tool-specific file a stub: “Read AGENTS.md in the repo root and follow it; the rules below are the only additions for this tool.” Tool quirks go in the stub, everything shared lives in exactly one place. This space moves fast, so check your tool’s current docs once a quarter, but the principle doesn’t change: one source of truth, pointers elsewhere.

The bar: every line prevents a real mistake

Think of the context file as onboarding a sharp junior developer who has infinite energy, perfect memory within a session, and zero knowledge of your project. You wouldn’t hand them a 200-page wiki. You’d give them the ten things that prevent the ten most common mistakes.

That’s the standard for every line: does this prevent a real mistake you’ve seen the agent make? If a line is philosophy, cut it. Agents follow concrete constraints. They ignore aspirations, because they were already trying to “write clean code” before you asked.

The five sections that matter

1. Stack and commands

The highest-value section in any context file is the boring one: how to build, test, and lint. Two or three commands the agent will run constantly, with the caveats that matter (“the full suite takes about 4 minutes; run a single file while iterating”). Without this, the agent guesses, and guesses wrong, burning loops on commands that don’t exist in your repo.

2. Architecture in five lines

Where the code lives and how it flows. “app/, Next.js routes. lib/, shared business logic. db/, schema and migrations.” That’s enough. The agent can read the rest of the tree itself; what it can’t infer is which parts are load-bearing and which are legacy.

3. Conventions that differ from the default

Don’t document standard practice, the model already knows it. Document where you diverge: “Database columns are snake_case; TypeScript is camelCase.” “All timestamps are stored as UTC and converted at the UI layer.” “Never use a raw hex value, always a design token.” Rules beat wishes, and conventions with one short example beat conventions described in prose.

4. Things that have bitten you

The highest-value lines in the file, because they’re the ones no model can derive from the code: “The orders table joins to users on email, not user_id.” “Don’t run migrations against the staging database; use the seed script.” “The payments module has no foreign key to users; join on customer_email.” Each line here is a debugging session you never have again.

5. What not to do

Explicit prohibitions work better than you’d expect: “Don’t add a new dependency without asking.” “Don’t refactor files unrelated to the task.” “Don’t write tests for generated code.” Anti-patterns from your actual history, stated as rules, are what separate a context file that changes behavior from one that’s decoration.

A worked example

Here’s a filled-in file for a small SaaS product. It’s 46 lines. Every line is there because it prevents a specific, observed failure.

# Ledgerline (billing SaaS)

## Commands
- Dev: `npm run dev`
- Test: `npm test -- <file>` while iterating; full suite `npm test` (~4 min)
- Lint: `npm run lint` (must pass before committing)

## Architecture
- `app/`, Next.js routes and API handlers
- `lib/`, business logic (billing in `lib/billing/`)
- `db/`, Prisma schema and migrations

## Conventions
- Database columns snake_case; TypeScript camelCase.
- All timestamps UTC in the database, converted in the UI.
- Money is integer cents everywhere. Never floats for amounts.
- UI colors come from design tokens in `lib/tokens.ts`, never raw hex.

## Gotchas
- `orders` joins to `users` on `email`, not `user_id`.
- Webhook handlers must be idempotent: Stripe retries deliveries.
- Don’t run `prisma migrate` against staging; use `npm run db:seed`.

## Don’t
- Don’t add dependencies without asking.
- Don’t refactor outside the task’s scope.
- Don’t edit generated files in `lib/gen/`.
Enter fullscreen mode Exit fullscreen mode

Notice what’s not in it: no tutorial on how billing works, no style philosophy, no secrets. The webhook line alone is worth the whole file. Whoever wrote it clearly lost an afternoon to duplicate Stripe deliveries once, and now no agent on this repo ever will.

Length and layout: write for the skim

Context files compete with your actual code for the agent’s attention. The pattern that holds up:

  • Root file under ~100-150 lines. Essentials only: commands, hard rules, layout, gotchas.
  • Details colocated. Directory-specific conventions go in a nested file in that directory (components/AGENTS.md), which most agents pick up when working there.
  • Link, don’t inline. “See docs/auth.md for the auth flow” beats pasting the auth flow into the root file.
  • Match reality. If the codebase doesn’t actually follow a convention, writing it down teaches the agent to produce code that clashes with everything around it. Aspirational rules are worse than none.

The file is half the system: prompting that uses it

A good context file handles what’s always true. Your prompts still have to handle what’s true this time. The patterns that survive contact with real, messy codebases:

Point at the code, don’t describe it. “In app/auth/signup.tsx, add email validation matching the pattern in app/auth/login.tsx” beats “add validation to the signup form.” File paths are facts; descriptions are interpretations the agent has to guess at.

State the constraints before the task. Agents optimize for the request as stated. “Don’t add dependencies. Keep the change under 100 lines. This table has 40M rows; the migration must not lock writes.” If you don’t state a constraint, it doesn’t exist.

Ask for a plan on anything non-trivial. For changes touching more than two files: “Propose a plan first. Don’t write code yet.” Reviewing a plan costs a paragraph; catching the same misunderstanding in a 400-line diff costs an afternoon.

Hand over the failing state. “It’s broken” produces guesses. The exact error, the stack trace, the reproduction steps, and what you already tried produce fixes. The agent can’t see your screen, so put your screen in the prompt.

Demand the boring parts explicitly. End significant prompts with: “Include tests for the new behavior, updated docs if the API changed, and a note on what you deliberately didn’t handle.” That last clause is the highest-value sentence in prompting. It forces the agent to surface its own blind spots instead of silently shipping them.

And when the agent gets it wrong twice, suspect the prompt before the model: an unstated assumption, a missing file reference, or two tasks wearing a trench coat. Split, specify, retry.

Maintenance: the file rots faster than the code

Commands change, rules get superseded, tools arrive. Treat staleness as a bug:

  • Put a last-reviewed date at the top and actually review it: when onboarding a human breaks, or the agent “forgets” the same thing twice.
  • Delete rules that stopped mattering. A wrong instruction is worse than a missing one.
  • Grow it by scar tissue: after any session where the agent made a preventable mistake, add the one line that would have prevented it. A month of this produces a file worth more than most documentation.
  • Test the file, not just the code. Watch a fresh agent session and note every moment it does something the file should have prevented. Each one is a missing or unclear rule. Two sessions of this usually halves your correction rate.

Four ways context files die

  • The wishlist. Aspirations instead of rules (“write clean code”). The agent nods and changes nothing. Covered above: rules or it didn’t happen.
  • The novel. 500 lines of everything anyone ever learned about the project. The agent skims, the important rules drown, and nobody dares edit it. The fix is subtraction, not better formatting.
  • The zombie. Written once at adoption, never updated. Six months later it documents commands that no longer exist and bans a library the team adopted in March. A wrong instruction is worse than a missing one, and zombies are mostly wrong instructions.
  • The mirror. A copy of the README, or of another tool’s context file, drifting one edit behind the original. Two sources of truth is zero sources of truth. Point, don’t copy.

The checklist

  • [ ] Build/test/lint commands, verified current, with runtimes noted
  • [ ] Architecture in five lines or fewer
  • [ ] 3-5 hard rules and explicit prohibitions
  • [ ] Conventions that differ from defaults, one example each
  • [ ] Gotchas from your actual incident history
  • [ ] Under ~150 lines at root; details nested or linked
  • [ ] No secrets, no tutorials, no aspirations
  • [ ] Last-reviewed date at the top

Context engineering isn’t prompt magic. It’s documentation discipline, the same skill that makes a good README, applied to a reader that executes what it reads. The teams getting the most from coding agents aren’t writing cleverer prompts. They’re writing better repos, and then prompting like the file is watching.


This guide is published on NotVibesCoded, where it sits with the rest of the field guides on context engineering, PR review, and shipping AI-built software without the slop.

Top comments (0)