AI coding

How to Keep a Project Context File Accurate

Antonio Evans11 min read

A split scene: on the left, a project context file open on screen with a highlighted line for a build command; on the right, a code repository showing a renamed script file.
Key points

Key points

  1. 1Give every section of the context file a named owning engineer, and update the section in the same pull request that changes the behavior it describes.
  2. 2Add a CI job that runs every command the file lists and fails when a script, path or test runner it mentions no longer exists.
  3. 3Review the whole file on a fixed cadence: monthly for repositories that ship often, quarterly for stable ones, plus an immediate pass after any trigger event.
  4. 4Shrink the file over time instead of growing it, because stale lines load on every request and mislead the agent.

Why a stale context file is worse than no file at all

A context file (AGENTS.md, CLAUDE.md, or a CONTEXT.md you maintain yourself) is read at the start of every agent session, so it behaves like code that runs before anything else. The open AGENTS.md format exists precisely to hold "the extra, sometimes detailed context coding agents need: build steps, tests, and conventions" separately from the human-facing README the AGENTS.md project. Claude Code loads its memory files at the start of every conversation and treats them "as context, not enforced configuration" the Claude Code memory docs. That combination is the whole problem: the file is authoritative by convention, unenforced by machinery, and read every single time.

That last property is what makes staleness expensive. Matt Pocock's guide points out that every token in an AGENTS.md file is loaded on every request regardless of relevance, and quotes the "instruction budget" idea that frontier reasoning models follow roughly 150 to 200 instructions with reasonable consistency the AGENTS.md guide on aihero.dev. An obsolete line does not sit idle. It competes for attention with the lines that still matter. Pocock also describes staleness as poisoning context, with documented file paths as the worst offender because paths change constantly the same guide.

There is a second cost that is easy to miss. Addy Osmani summarizes two 2026 studies on generated versus hand-written context files and concludes that a good mental model is to treat AGENTS.md as "a living list of codebase smells you haven't fixed yet, not a permanent configuration," adding that auto-generated files hurt performance and inflate cost by duplicating what agents can already discover Osmani's write-up. Both papers point the same way: content the agent can rediscover by reading the repository is pure overhead, and only non-discoverable content earns its place.

So the maintenance question is not "how do we keep everything in the file up to date." It is "how do we keep the small set of non-discoverable facts correct, and delete the rest." The rest of this article is a system for doing that.

Choosing what the file is allowed to say

You cannot maintain a file whose scope you never defined. Before assigning owners, settle on four allowed content types and refuse everything else.

AllowedWhy it earns its placeExample
Exact commandsThe agent can guess a command but cannot know which one your CI runspnpm turbo run test --filter api
Non-obvious conventionsStyle is invisible in a single file but consistent across the repo"No any types without a justification comment"
Tooling and setup trapsDiscoverable only by failing once"Migrations must run through uv run, never bare manage.py"
Off-limits pathsPrevents damage the agent cannot infer"Never touch legacy/billing"

The AGENTS.md reference example follows exactly this shape: a dev environment section with the package-jump and workspace-add commands, a testing section that names the CI plan location and the single-package test command, and a PR title format the AGENTS.md project. The Real Python walkthrough builds the same file section by section around pinned setup, conventions, structure, quality gates and constraints, and its central claim is that pinning the dependency manager and style stops the agent from guessing Real Python's AGENTS.md tutorial. The NeuralNine walkthrough reaches the same conclusion with a concrete failure: a Django agent that does not know the project uses uv runs the wrong migration command, and one line in the context file fixes it the NeuralNine video.

Everything else, the architecture prose, the folder tree, the glossary, belongs in a document the agent can find and read on demand. Birgitta Böckeler's primer on context engineering for coding agents frames this as deliberate curation: an agent's effectiveness goes down when it gets too much context, and rules files should be built up gradually rather than filled at the start Martin Fowler's site. Anthropic's own engineering post explains the mechanism, noting that recall degrades as context grows and that context should be treated as a finite resource with diminishing returns Anthropic Engineering.

Decision rule: if a competent engineer could answer the question by reading three files in the repository, it does not go in the context file. If the answer requires knowing what the team decided, it does.

The trigger list: when an update is mandatory

Cadence reviews are not enough. The changes that break context files are specific and identifiable, and each one should force an edit in the same pull request. Write the list down and put it in the file's own preamble so reviewers see it.

Mandatory triggers:

  1. A build, test or lint command changes. A renamed script, a new test runner, a switch from npm to pnpm. This is the highest-frequency trigger in most repositories.
  2. A new service, package or deployable is added. The file must gain its commands and its boundaries, or the agent will work in it with nothing.
  3. The folder layout changes. Moving the API handlers invalidates every path mention.
  4. A dependency upgrade changes setup steps. A runtime bump that alters installation, environment variables or migration flow.
  5. A new off-limits area appears. A vendored directory, a generated folder, a licensed module.
  6. A PR review catches the agent making the same wrong assumption twice. The Claude Code docs list exactly this, alongside repeated corrections typed into chat, as the moment to write something down the Claude Code memory docs.

Trigger six deserves emphasis because it is the cheapest signal you have. Every time you type the same correction into a chat session, you have discovered a missing context line. Every time you type a correction that contradicts the file, you have discovered a stale one.

The hierarchy matters too. Osmani argues a single root file is insufficient for any codebase of real complexity and that what you need is a hierarchy of files placed at the module level Osmani's write-up. The Claude Code docs describe a comparable scoping model: files above the working directory load at launch, files in subdirectories load on demand, and path-scoped rules let you attach instructions to specific file types the Claude Code memory docs. In a monorepo, this turns one giant maintenance job into one small job per package, each with its own owner and its own trigger events.

Owners per section, and a cadence that matches the rate of change

Ownership is what converts a wish into a task. Assign each section to one named engineer, not a team, and record the owner in the file itself. A minimal header does the job.

<!-- context-owner: @dana build-and-test 2026-03-01 -->
<!-- context-owner: @ravi conventions 2026-03-01 -->

The dated comment is a low-tech but effective audit trail. A reviewer can see how long a section has gone untouched without opening git history, and a script can flag sections past their review window.

Repository profileMerge frequencyFull review cadenceSection owner rotation
Product repo, multiple deploys per dayHighMonthlyFixed, reassigned on team change
Internal service, weekly releasesMediumQuarterlyFixed
Library or tool, occasional releasesLowTwice a yearFixed, reviewed at each release
Archived or frozenNoneOn reactivationWhoever reactivates it

The rule behind the table: cadence should track the rate at which the described behavior changes, not the calendar. A repository that changed its test command three times in two months has earned a monthly review. One that has not touched its build in a year does not need one.

Whoever owns a section is also the default reviewer when that section changes in someone else's pull request. This is the same principle as code ownership, applied to a document that executes. The Packmind context engineering guide makes governance an explicit practice, with context files version-controlled alongside code and reviewed like code, and describes periodic context gap audits as part of the maintenance loop the Packmind guide. The NVIDIA NeMo Agent Toolkit developer guide shows the same discipline at a larger scale, splitting rule files by topic under a directory tree with a meta-rule file that defines naming and format conventions for new rules the NVIDIA guide. That meta-rule matters for maintenance: it tells contributors where a new section goes, which is the difference between a structured file and a pile.

Checks that catch drift automatically

Owners and cadence catch intentional changes. A CI check catches the rest, including the changes nobody noticed. There are three checks worth building, in ascending order of effort.

Check 1: every referenced path exists. Extract path-like strings from the file and confirm each resolves. This alone catches the most damaging class of staleness.

Check 2: every referenced script exists. For a JavaScript repository, look up each named script in the package manifest. For Python, confirm the module and tool the file names are installed.

Check 3: every listed command runs. This one is worth the cost. It executes the commands, and if the test command has been renamed, the job goes red on the pull request that broke it.

A compact version of checks 1 and 2 in a single script:

import re, sys, pathlib, json, tomllib

CONTEXT = pathlib.Path("AGENTS.md")
text = CONTEXT.read_text()
problems = []

# 1. Paths written in backticks that look like files must exist
for candidate in re.findall(r"`([\w./-]+/[\w./-]+)`", text):
    if not pathlib.Path(candidate).exists():
        problems.append(f"missing path: {candidate}")

# 2. npm script names must be present in package.json
pkg = pathlib.Path("package.json")
if pkg.exists():
    scripts = json.loads(pkg.read_text()).get("scripts", {})
    for name in re.findall(r"(?:npm run|pnpm) ([\w:-]+)", text):
        if name not in scripts:
            problems.append(f"missing script: {name}")

# 3. Python commands named in the file must be installed
for tool in re.findall(r"(?:uv run |poetry run )([a-z][\w-]+)", text):
    if not any(pathlib.Path(p).name.startswith(tool) for p in
               __import__("shutil").which(tool) and [__import__("shutil").which(tool)] or []):
        problems.append(f"missing tool: {tool}")

if problems:
    print("\n".join(problems)); sys.exit(1)

Wire it into whatever CI system you already run. GitLab's pipeline syntax lets you attach a plain script job and fail the pipeline on a non-zero exit the GitLab CI/CD YAML reference. Nothing here needs a new platform.

For the harder question, whether the documentation still describes what the code now does, a language model can compare a merge diff against the context file and open a follow-up pull request. Dosu publishes a worked GitHub Actions example that does this with Claude Code: on merge to main, the workflow checks out the repository, extracts the diff, hands it to the model alongside existing documentation, and opens a follow-up PR when something drifted the Dosu walkthrough. The same post is honest about the limits: the prompt needs ongoing tuning, there is no memory between runs, and it is not production-grade as written. Treat that kind of workflow as a reviewer suggestion, not a gate.

One important caveat applies to all three checks. Claude Code's documentation is explicit that memory files are context, not enforced configuration, and that a PreToolUse hook is the mechanism for blocking an action regardless of what the model decides the Claude Code memory docs. A passing context check does not enforce anything on the agent. It only proves the document matches the repository. Enforce behavior with hooks, CI gates on the actual build, and branch protection.

If you are running agents across several repositories or providers and want the model side of this to be one integration rather than several, Quanta Inference exposes text, image, video, audio and embedding models through one OpenAI-compatible API key, which keeps the drift-checking workflow identical across projects: https://quantaintelligence.ai/inference

A worked example with numbers

Suppose a repository with six engineers and 40 merges a week. Take a file of 180 lines that references 25 commands and 14 paths. Without any maintenance process, the following happens over a quarter.

EventOccurrences per quarterContext lines affectedCaught without a process?
Test script renamed26Usually not
Path moved during refactor49No
New package added30 (missing)No
Repeated agent mistake1111 (missing)Only if someone writes it down

By the end of the quarter, roughly 15 of the original 40 concrete references are wrong, and 14 lines that should exist do not. The file is longer than it started and less true. This is the failure mode Pocock describes when he warns about AGENTS.md files turning into a "ball of mud" through hundreds of incremental additions and no style pass the aihero.dev guide.

Now run the process. The path check catches all four moves in the pull request that made them. The script check catches both renames. The trigger list forces an entry for each of the three new packages. The repeated-mistake trigger converts maybe seven of the eleven corrections into permanent lines during the weekly review. What survives to the quarterly full review is a file that is roughly the same size, with every line still true.

The saving is measurable in review time. A full review of a 180-line file takes an experienced engineer perhaps 25 minutes. Four of those a year is under two hours. The alternative, an agent that confidently runs a test command deleted six weeks ago and reports success from the wrong suite, costs far more than that in one incident. The empirical study of developer-provided context across 401 open-source repositories found that excessive or unoptimized context leads to less accurate responses and higher cost, which is the same argument from the other direction the arXiv study.

Cleaning up a file that has already drifted

Most teams reading this are not starting from a clean file. Here is a repair pass that fits in a single afternoon.

  1. Count the claims. Highlight every command, path, version and convention. If the number is above roughly 40, you have a pruning problem before a maintenance problem.
  2. Delete anything the agent can rediscover. Folder listings, architecture summaries, framework boilerplate. The ETH Zurich results summarized by Osmani suggest auto-generated content is redundant rather than harmful in itself, which means deleting it costs you nothing Osmani's write-up.
  3. Test every command by running it. Not by reading it. A command that fails is deleted or corrected, and the correction is what tells you the pipeline needs a check.
  4. Split anything module-specific into a scoped file. One root file for repository-wide commands and conventions, one per package for its own commands and traps, following the on-demand loading model described for Claude Code the Claude Code memory docs.
  5. Assign owners and dates to what remains. Anything you cannot assign to a person is a candidate for deletion.
  6. Land the CI check in the same pull request. A cleanup without a check is a cleanup with a timer attached.

One last habit that prevents regrowth. When you add a rule, write it as a specific instruction with a verification step, not as an aspiration. Cursor's rules documentation emphasizes persistent, reusable context at the prompt level, which only works if each rule says something checkable the Cursor rules docs. "Run make test-api after changing services/api" survives review. "Write high-quality tests" does not, and it is the kind of line that never gets deleted because nobody can prove it wrong.

For teams that would rather have an expert own the context layer across a line of business than staff it internally, Quanta Experts reads your repository context, does the work and hands back finished deliverables: https://quantaintelligence.ai/agents

FAQ

FAQ

How often should a context file be reviewed?

Match the cadence to the rate of change: monthly for repositories with many merges per week, quarterly for internal services, twice a year for libraries with occasional releases. The full review is a backstop, not the main mechanism. The trigger list and the CI check do most of the work between reviews.

Should the context file repeat the README?

No. The AGENTS.md project keeps the two separate on purpose, with READMEs staying concise and focused on human contributors while the context file carries the build steps and conventions agents need the AGENTS.md project. Duplicating content creates two places to update and two chances to disagree.

What should happen when the agent makes the same mistake twice?

Write the correction into the file in the same session. The Claude Code documentation lists a repeated mistake, a review comment the agent should have anticipated, and retyping last session's correction as the moments to add to its memory file the Claude Code memory docs. These are the highest-value additions you will make, because each one is a demonstrated gap.

Can a CI check replace the review?

No. CI can prove that a path or script named in the file exists, which catches the most common and most damaging failures. It cannot judge whether a convention still reflects the team's intent, whether a section has grown too long, or whether a new service needs context it does not have yet.

Does the file need to be duplicated for every agent tool?

Usually not. AGENTS.md is designed as an open format that works across many agents, and Claude Code can read a repository's AGENTS.md in place of CLAUDE.md the Claude Code memory docs. Where a tool insists on its own filename, a symlink keeps one source of truth and avoids the version drift that comes from maintaining parallel files.

Sources

Sources

  1. AGENTS.md
  2. How Claude remembers your project - Claude Code Docs
  3. A Complete Guide To AGENTS.md
  4. Stop Using /init for AGENTS.md
  5. How to Write an AGENTS.md File for a Python Project
  6. How I Write My AGENTS.md Files - Best Practices - YouTube
  7. Context Engineering for Coding Agents - Martin Fowler
  8. Effective context engineering for AI agents - Anthropic
  9. Context Engineering Best Practices for AI-Powered Dev Teams (2026)
  10. Cursor Rules Developer Guide, NVIDIA NeMo Agent Toolkit (1.2)
  11. CI/CD YAML syntax reference
  12. How to Catch Documentation Drift with Claude Code and ...
  13. An Empirical Study of Developer-Provided Context for AI ...
  14. Rules | Cursor Docs
About the author

About the author

Antonio Evans
Antonio Evans

Antonio Evans is the founder of Quanta Intelligence and a fractional CTO who builds HIPAA-ready AI systems for health and life-science companies. Before that he was technical co-founder of FriendsEAT for twenty years, CEO of Socialdraft, and a data engineer at IBM. Antonio lives with his dog Santino in Lisbon, Portugal.

All articles