Setting Up Context: Rules Files and Project Config

You run the same prompt in two repos and get two very different results. One writes code that looks like yours; the other invents a testing library you do not use. The difference usually is not the prompt. It is what each repo told the tool about itself before you typed anything.

That “telling” happens through a rules file and a few project config settings. Set them once, and every session starts from your facts instead of the model’s guesses.

Rules files: conventions the tool reads on every request

Most AI coding tools look for a plain-text file at the root of your project and inject its contents into the context window at the start of a session. The file goes by different names depending on the tool:

  • AGENTS.md, the cross-tool convention that several agents now read.
  • CLAUDE.md, read by Claude Code.
  • .cursorrules (or files under .cursor/rules/), read by Cursor.

They all do the same job: give the model standing instructions about this project. The tool does not run the file or parse it into a schema. It pastes the text in as part of the prompt, so the model reads it the way it reads your request. That is the whole mechanism. A rules file is just context you wrote down once instead of retyping every session.

flowchart LR
    RULES["Rules file<br/>(AGENTS.md)"] --> CTX[Context window]
    REQ[Your request] --> CTX
    FILES[Files it reads] --> CTX
    CTX --> MODEL[Model plans<br/>the edit]
    MODEL --> DIFF([Diff])

As article 01 put it, context selection is the single biggest driver of output quality. The model only knows what is in its context window. A rules file is the one piece of that context you control fully and in advance, so it is the setup step that pays back the most for the least effort.

What belongs in a rules file

The goal is high signal per line. Everything in the file is pasted into context on every request, so a bloated rules file does two bad things: it costs tokens, and it buries the rules that matter under ones that do not. Aim for a page, not a manual.

Put in the things a competent new engineer would ask on day one:

  • Stack and versions. Language, framework, and the versions that matter. “Python 3.12, FastAPI, Postgres 16” stops the model from writing code for the wrong major version.
  • Conventions. How you name things, how you structure a module, which patterns you prefer. This is what makes generated code look like yours.
  • A directory map. A few lines on where things live, so the agent’s search starts in the right place instead of guessing.
  • Do and do-not rules. The sharp edges. “Do not add new dependencies without asking.” “Use the existing db.session, do not open raw connections.”
  • How to run tests. The exact command. An agent that can run your tests can check its own work; one that guesses the command cannot.

Leave out anything the model can see for itself by reading the code. You do not need to paste function signatures or restate what a well-named file already says. The rules file is for the things that are not obvious from any single file: cross-cutting conventions, project-wide constraints, and the commands that are not written down anywhere in the repo.

Why not just put everything in the rules file to be safe?

Because context is not free, and more is not better.

Every token in the rules file is sent on every request, so a long file costs money and, more importantly, dilutes attention. When the ten rules that matter sit inside two hundred lines of nice-to-haves, the model weighs them all the same. A tight file of the rules you actually care about gets followed more reliably than an exhaustive one.

The test for a line: would the code be wrong or off-convention without it? If not, cut it. You can always add a rule back when you catch the tool getting something wrong.

A compact example

Here is a rules file for a small FastAPI service. Notice how short each section is; it reads like a checklist, not documentation.

# Project: payments-api

## Stack
- Python 3.12, FastAPI, SQLAlchemy 2.x, Postgres 16
- Package manager: uv (not pip). Add deps with `uv add`.

## Layout
- `app/routers/`  HTTP endpoints, one file per resource
- `app/services/` business logic, no HTTP or SQL here
- `app/models/`   SQLAlchemy models
- `tests/`        pytest, mirrors the app/ tree

## Conventions
- Endpoints are thin: validate, call a service, return.
- All money is integer cents, never floats.
- Use the shared `db.session`; do not open raw connections.

## Do not
- Do not add dependencies without asking first.
- Do not edit files under `app/migrations/` by hand.

## Tests
- Run: `uv run pytest -q`
- A change is not done until the relevant tests pass.

Every line here changes what the model produces. “Money is integer cents” alone prevents a category of bugs. “Endpoints are thin” keeps generated code in the shape of the rest of the codebase.

Project config beyond the rules file

The rules file tells the tool how to behave. A couple of other settings control what it is allowed to see and how fast it can find things.

Ignore files. Most tools respect your .gitignore, and several add their own (.cursorignore, or an ignore list in the tool’s settings). Use them to keep two kinds of things out of context: noise and secrets. Build output, node_modules, lockfiles, and generated code are noise; they waste the agent’s search budget and can lead it to edit files that get regenerated. A .env file or a credentials directory is worse than noise: you do not want its contents pulled into a prompt and sent to a model provider. Excluding those paths is a small habit with real payoff.

Indexing. Tools that search your repo (Cursor is the clearest example) build an index of your code so retrieval is fast and relevant. Usually this just works, but two things are worth knowing. First, a fresh clone or a big change may need a re-index before the tool “sees” new files; if the agent seems blind to code you know exists, check the index. Second, indexing means the tool has read your code to build embeddings, so treat the ignore file as your control over what gets indexed in the first place.

flowchart TB
    REPO[Your repo] --> IGN{In ignore<br/>file?}
    IGN -->|yes| SKIP[Skipped: not<br/>indexed or read]
    IGN -->|no| IDX[Indexed and<br/>searchable]
    IDX --> AGENT[Agent can<br/>find it]

Together these settings define the boundary of what the agent works with. The rules file shapes the behavior inside that boundary. Both are context you set once and then benefit from on every request, which is exactly why they pay back the ten minutes they take.

Common beginner mistakes

  • No rules file at all. Every session starts cold on your conventions, so you retype them in each prompt or accept off-convention code.
  • A bloated rules file. Two hundred lines of everything dilutes the ten rules that matter and burns tokens on every request.
  • Restating the code. Pasting signatures or file summaries the model can read for itself. Keep the file to what is not visible from any single file.
  • Forgetting the test command. An agent that cannot run your tests cannot check its own work, and you lose the tightest feedback loop it has.
  • Ignoring the ignore file. Letting node_modules and generated code into search wastes budget; letting secrets in is a real risk.
  • Assuming the index is fresh. After a big change or a new clone, the tool may not “see” new code until it re-indexes.

Questions you will face in production

“Should I commit the rules file to the repo?” Yes, for the shared conventions. A committed rules file means every engineer’s tool works from the same facts, and it stays in sync with the code through normal review. Keep personal, machine-specific preferences in a local, un-committed override if your tool supports one, so the shared file stays about the project, not about you.

“The tool keeps ignoring a rule I wrote. Why?” Usually the rule is buried or vague. Move the ones that matter near the top, phrase them as sharp do or do-not lines, and cut the filler around them so they stand out. If a rule is still ignored, it may be fighting something the model saw directly in the code; the code almost always wins, so fix the code or make the rule more explicit.

“Does a rules file replace pointing the tool at the right files?” No. The rules file carries standing conventions; pointing at files carries what is relevant to this task. You still name the files a change touches. The rules file just means you do not also have to re-explain the stack and conventions every time.

What to remember

  • A rules file (AGENTS.md, CLAUDE.md, .cursorrules) is standing instructions the tool pastes into context on every request.
  • The mechanism is plain: it is text injected into the prompt, not a parsed config.
  • Put in stack and versions, conventions, a directory map, do and do-not rules, and the test command.
  • Keep it tight; a bloated file wastes tokens and buries the rules that matter.
  • Ignore files keep noise and secrets out of context; check indexing when the tool seems blind to code.
  • A rules file is context you set once, and context is the biggest driver of output quality.

What to study next

A rules file sets your standing context; the next skill is making each individual request land. That is prompting coding agents: how to frame a task, scope it, and give the agent a path it can follow. With good rules plus a good prompt, you supply both the constant context and the per-task context, which is most of what separates a great result from a guess.

Further reading

Where this article comes from. This is a synthesis of common practice in AI engineering as of 2026, not a citation of any single paper. The sources above are where the mechanics come from. If you find an error or have a better source for a claim, the article gets fixed within a day, send me a note.


Auto-marks when you reach the end. Click to toggle.

If this helped, buy me a coffee

Everything is free. Tips keep me writing the rest.

Buy me a coffee →