· 8 min read ·

Context Anchoring and the Decision Debt That Predates AI

Source: martinfowler

Every AI coding session starts with amnesia. You open a new conversation, describe your project from scratch, re-explain that you are using Postgres not SQLite, remind it that the API layer is versioned differently from the frontend, and re-establish all the constraints that took weeks of discussion to settle. Then you close the tab, open a new one, and do it again.

Rahul Garg calls this problem out directly in his context anchoring article on MartinFowler.com. The fix he proposes is simple in form but deceptively demanding in practice: externalize the decision context into a living document that travels with the codebase and gets fed into the AI’s context at the start of every session. The idea is not novel in the abstract, but the framing matters because it positions this document as an active artifact rather than passive documentation.

Before looking at how to build a good anchor document, it is worth understanding why the problem exists and why the existing solutions have not been enough.

The Memory That Never Made It Into the Repo

Software projects accumulate decisions constantly. Some decisions are large and deliberate: switching ORMs, choosing a deployment model, settling on a testing strategy. Others are small and transient: the choice to use camelCase in JSON payloads because the frontend team preferred it, the decision not to upgrade a dependency because of a known incompatibility with a vendor library. Both types matter. Both types routinely go undocumented.

The Architecture Decision Record format, popularized by Michael Nygard in 2011, was the most serious attempt to capture this knowledge. An ADR records context, decision, status, and consequences in a short Markdown file committed alongside the code. Nat Pryce’s adr-tools project gave teams a CLI workflow for managing them. Many teams adopted the format and abandoned it within months.

The abandonment rate is not because ADRs are a bad idea. It is because the feedback loop is broken. You write an ADR when you make a decision, file it in /docs/decisions/, and it sits there. Nobody reads it before asking you a question you already answered in that file. It does not improve the next conversation, human or AI. The record exists but does not participate.

Context anchoring inherits the best of the ADR tradition and discards the part that makes it inert. Instead of a growing archive of historical records, you maintain a single present-tense document that summarizes the current implications of all significant decisions, written not for posterity but for orientation.

Convergence Across Tooling

What makes context anchoring feel timely rather than theoretical is that every major AI coding assistant has independently converged on exactly this artifact over the past two years.

Claude Code reads from CLAUDE.md at the project root. GitHub Copilot introduced .github/copilot-instructions.md for workspace-level instructions. Cursor uses .cursorrules. Aider supports CONVENTIONS.md and similar named files. Codex and the OpenAI Assistants API have their own system prompt injection mechanisms.

The convergence is not coincidental. It is the natural response to a hard constraint: LLMs have no persistent state between sessions, but real software projects have enormous amounts of accumulated context that should not need to be rebuilt from scratch in every conversation. The file-in-the-repo pattern solves this with zero infrastructure: no vector database, no external memory service, just a text file that gets loaded into the context window alongside your first prompt.

What Garg’s framing adds to this convergence is a name for the practice and a set of principles for doing it well, rather than just dropping a random file in the repo and hoping it helps.

What Goes In the Document

An anchor document is not a README. A README explains what the project does and how to get started. An anchor document explains what the project has decided and why, in enough detail that an AI assistant can avoid re-litigating settled questions and respect constraints that are not visible in the code itself.

A minimal but effective anchor document typically covers:

Technology choices with rationale. Not just “we use Redis” but “we use Redis for session storage because the team evaluated DynamoDB and found the latency floor unacceptable for our EU region users.” The rationale is what prevents an AI from helpfully suggesting you switch.

Constraints that are not visible in the code. Things like “we cannot upgrade past Node 18.x because of the vendor SDK” or “the CI environment has no internet access at build time.” These constraints exist in people’s heads and in Slack threads. Without the anchor document, the AI will violate them repeatedly.

Naming and structural conventions. If your project has specific patterns that diverge from idiomatic conventions in the language or framework, document them. An AI trained on millions of public repos will default to whatever is most common, which may not be what your codebase does.

Active work and near-term decisions. This is the part that most teams skip and that makes the biggest difference. A section that says “we are currently migrating from REST to GraphQL, the old endpoints will remain until Q3” gives the AI working context about the current state of the system, not just its intended final state.

Here is a skeletal example of what this looks like in practice:

# Project Context

## Stack
- Runtime: Node 18.x (cannot upgrade, blocked by vendor-sdk@2.x)
- Database: PostgreSQL 15 via pg-promise (not Prisma, not TypeORM)
- Cache: Redis 7, used only for session tokens and rate limit counters
- API: REST, JSON:API spec compliant

## Decisions In Effect
- Auth is JWT, tokens are short-lived (15m), refresh tokens are httpOnly cookies
- No ORM migrations framework; schema changes are hand-written SQL in /migrations/
- All async database calls use pg-promise transactions even for reads (performance acceptable)

## Constraints
- Build environment has no outbound internet; all deps must be in package-lock.json
- PII data cannot leave the EU region; no US-hosted third-party logging services

## Current Work
- Migrating user notification system from polling to WebSockets (in progress, ~60% done)
- Rate limiting middleware is under active refactor, do not modify until complete

This is not a design document. It is a briefing. Every line is there because without it, the AI will make a wrong assumption at some point.

The Living Document Problem

The word “living” in Garg’s framing is the hard part. A document that accurately describes the project on day one and has not been updated in six months is worse than no document at all, because it actively misleads rather than just failing to help.

The discipline required to maintain an anchor document is different from the discipline required to write documentation. Documentation is written once, at the end of a decision. An anchor document needs to be updated whenever a decision changes, a constraint is lifted, or the current state of the system shifts. That means the update belongs in the same commit as the code change that motivated it.

This is where the ADR tradition is useful again, not as a replacement for the anchor document but as a companion. You can maintain the full decision archive in /docs/decisions/ for historical reference and use the anchor document as a curated summary of what is currently in effect. When a decision becomes obsolete, you archive the ADR and remove its implications from the anchor document. The anchor document stays current; the ADR archive preserves the history.

The failure mode to watch is letting the anchor document grow unchecked. If it becomes a hundred-line essay, the AI has to process too much to find what is relevant, and humans stop reading it before making changes. Keep it short enough to read in two minutes. Prune it aggressively. If a constraint no longer applies, remove the line rather than adding a note that it used to apply.

Why This Is Different From Prompt Engineering

There is a tempting conflation of context anchoring with prompt engineering. Prompt engineering is about how you phrase individual requests to get better responses from the model. Context anchoring is about what the model knows before you make any request.

The distinction matters practically. A well-engineered prompt does not help you if the model does not know the constraints of your project. And a well-maintained anchor document reduces the amount of prompt engineering you have to do, because the model starts from an informed position rather than a blank one.

The anchor document is also fundamentally different from a system prompt in the conversational AI sense. System prompts are set by the application developer and are invisible to the user. An anchor document is owned by the project team, committed to version control, visible to everyone, and changes through the same review process as the code it describes. This makes it trustworthy in a way that opaque system prompts are not: you can see what the AI has been told, and you can change it.

The Organizational Implication

For teams rather than individual developers, context anchoring has a subtle but important effect on onboarding. A new team member who reads the anchor document before their first session gets the same orientation as a senior developer who has been on the project for two years. The knowledge that usually lives in someone’s head or in a three-hour onboarding call is written down and kept current.

This is not a replacement for mentorship or code review. But it reduces the surface area of the “why” questions that new contributors have to ask, which frees up time for the conversations that actually require human judgment.

The same logic applies to AI assistants. The anchor document is not a crutch for a bad AI. It is the minimum context that any intelligent collaborator needs to contribute usefully to a project that has real history and real constraints. Expecting an AI to infer that history from the code alone is like expecting a new contractor to understand your deployment process by reading the Dockerfile.

Getting Started Without Overthinking It

The failure mode for most teams adopting this practice is trying to write the perfect anchor document upfront. That leads to a long, unfocused document that nobody maintains.

A more sustainable approach: start with the three decisions that came up in your last AI session where the assistant made a wrong assumption. Write one or two sentences per decision, explaining the choice and why. Commit it as CLAUDE.md or .context/project.md depending on your tool. Add to it the next time the AI gets something wrong that a new teammate should have known.

After two or three weeks, you will have a document that reflects the actual friction points in your project rather than a theoretical taxonomy of everything the AI might need to know. That document will be more useful and more likely to stay current than anything written in a single planning session.

Context anchoring will not fix a fundamentally unclear project. It will not compensate for an AI that is a poor fit for your language or framework. But it closes the gap between what an AI assistant could do with full context and what it actually does when starting from nothing, which for most projects is a very large gap indeed.

Was this interesting?