· 7 min read ·

Your Anchor Document Is a System Prompt for the Whole Project

Source: martinfowler

Software projects accumulate decisions. Some of them make it into commit messages. Some end up in Confluence or Notion, where they slowly become inaccurate. Many live only in the heads of the people who made them, which means they disappear when those people move on, or simply when the conversation that produced them ends.

Rahul Garg’s article on Martin Fowler’s site addresses a specific version of this problem in AI-assisted development: the context that informs a decision made in an AI session is almost always lost before the next session begins. Garg calls the solution “context anchoring,” which means externalizing decision context into a living document that travels with the project rather than staying trapped in a chat history.

The idea is sound. The mechanics of why it works, and what those mechanics imply about how to write such a document, are worth understanding in some detail.

The Architecture of Forgetting

Language models do not remember. Each new session starts from zero, and the only thing that carries across sessions is what you explicitly provide. This is different from working with a colleague, who accumulates context passively over months of shared work.

But the problem is not only inter-session. Within a single long conversation, information degrades too. Research from 2023 (Liu et al., “Lost in the Middle”) demonstrated that language models perform significantly worse at retrieving information from the middle of long context windows compared to the beginning or the end. Early decisions in a long session progressively lose salience as new messages push them further from the positions where model attention is strongest.

This means that even a perfectly documented decision made at the start of a session can effectively vanish fifty messages later. The model is not ignoring it, but the probability that it will weight that information appropriately when generating the next response decreases as context grows. A constraint established in message three carries less force than the same constraint repeated in message forty-eight.

Context anchoring addresses both problems by keeping critical information outside the conversation entirely, in a document that gets provided fresh at the start of each session and sits at a consistent, high-salience position in the context.

Anchor Documents as System Prompts

When you look at how AI coding tools actually implement this pattern, a clearer mental model emerges. Claude Code reads a CLAUDE.md file from the project root at the start of every session. Cursor reads .cursorrules. GitHub Copilot reads .github/copilot-instructions.md. These files serve the same function: they establish persistent, project-level context before any conversation begins.

This is structurally identical to a system prompt. In the Anthropic and OpenAI APIs, system prompts occupy a privileged position at the top of the context window and carry higher salience than later user messages. Project-level anchor documents work the same way when read by coding tools. They run before anything else, establish the frame through which everything that follows is interpreted, and resist the degradation that affects information buried in the middle of a long exchange.

Understanding anchor documents as system prompts has practical implications. System prompts that work well share certain characteristics: they are specific rather than vague, they state constraints explicitly rather than implying them, and they distinguish between absolute rules and preferences. A CLAUDE.md that says “we use Postgres” is less useful than one that says “we use Postgres 16 with the pgvector extension; do not add new dependencies without discussion.”

Here is what a well-structured anchor section might look like in practice:

## Architecture decisions

- API layer uses Express with TypeScript, not NestJS. Deliberate choice to avoid framework lock-in.
- Database: Postgres 16. Migrations managed with golang-migrate, not Prisma migrate.
- No ORM. Raw SQL via the `postgres` npm package. Reason: a previous ORM caused N+1 issues that were difficult to debug through its abstraction layer.
- Auth: JWT tokens with 15-minute expiry, refresh token in httpOnly cookie. Do not suggest session-based auth.

## Code conventions

- All async functions use explicit error handling with a Result type, not try/catch. See `src/lib/result.ts`.
- Tests use node:test, not Jest. This is non-negotiable.

The reason annotations matter. Without them, the AI will often suggest alternatives to your stated approach because it has no way to know those alternatives were already considered and rejected. Including the reasoning transforms a rule into a constraint with known history, which the model handles differently from an arbitrary preference with no context behind it.

Why the Living Document Part Is Harder Than It Sounds

Garg’s framing emphasizes that the anchor document should be a living document, not a snapshot. This is where most implementations drift. Teams write an excellent context file during initial project setup, and then stop updating it as the project evolves.

The discipline required is different from traditional documentation. Documentation written for other humans is reviewed infrequently; staleness accumulates slowly and is often tolerated. An anchor document is consulted on every single AI interaction, which means its staleness surfaces immediately. If your anchor doc says “we use React 17” and your code has been on React 19 for six months, the AI will produce subtly incorrect guidance in ways that can be hard to trace back to a stale context file.

This immediate feedback loop is the genuine advantage that anchor documents have over traditional documentation. When documentation is wrong, humans often work around it silently and update their mental model without updating the document. When an anchor document is wrong, the AI’s outputs reveal the contradiction quickly. Teams that treat anchor document staleness as a defect, the same way they treat a failing test, maintain them far more reliably than teams that treat them as optional reference material.

A useful convention is to include a brief changelog section at the bottom of the anchor document, recording when major entries were last verified. It is low overhead and makes it easy to identify which sections are most likely to have drifted.

The Architecture Decision Record Connection

Michael Nygard popularized Architecture Decision Records (ADRs) in 2011 as a format for capturing the rationale behind significant decisions in a way that survives personnel changes. ADRs are typically stored in a docs/decisions/ directory, written once, and marked as superseded rather than deleted when decisions change.

Context anchoring is related but distinct. Where ADRs are comprehensive records of discrete decisions, anchor documents are distilled summaries of current state designed for rapid, repeated consumption. An ADR might be three paragraphs explaining why you chose event sourcing and what alternatives you considered. The equivalent anchor document entry is one line: “Event sourcing via EventStore. Reason: audit requirements. Do not suggest replacing with CRUD.”

The two practices complement each other well. ADRs provide the full historical record for humans trying to understand the evolution of the system. Anchor documents extract the operational constraints from that history for AI sessions. Teams with mature ADR practices have an easier time writing anchor documents because the reasoning is already documented somewhere; the work becomes curation rather than reconstruction from memory.

Teams without ADRs often find that writing an anchor document for the first time forces them to reconstruct why certain choices were made. This reconstruction exercise is useful on its own, and several teams report that it surfaces outdated constraints: decisions documented as fixed that have since been revisited, or rules that were added for a specific project phase and never removed.

What Belongs in an Anchor Document

Not everything that feels important belongs in an anchor document. The goal is to prevent the AI from making decisions you have already made, not to explain your entire codebase.

Things that belong:

  • Technology choices where alternatives exist and might plausibly be suggested (framework, database, testing library, package manager, bundler)
  • Constraints not visible from the code itself (regulatory requirements, performance budgets, infrastructure limitations imposed by the deployment environment)
  • Decisions made for reasons that are not obvious from the code (design choices driven by a past incident, a client contractual requirement, or a specific team capability)
  • Code conventions that deviate meaningfully from community defaults

Things that generally do not belong:

  • Information that can be inferred directly from the code or configuration files
  • Low-level implementation details that change frequently
  • General descriptions of how the project works, unless the structure is unusual enough to be actively misleading to someone with domain knowledge

The test for inclusion is whether the AI would make a different, worse decision without knowing this specific fact. If the answer is yes, it belongs in the document. If the AI could infer it from a quick read of the relevant files, it probably does not need to be explicitly stated.

The Onboarding Artifact Nobody Planned For

One consistent side effect reported by teams that maintain good anchor documents is that the files become excellent onboarding artifacts for new engineers. The distilled constraints and decision rationale that the AI needs turn out to be exactly what a new developer needs in their first week: not a comprehensive architecture diagram, but a clear statement of what the team has decided and why, without requiring them to dig through years of pull request comments.

This is not a coincidence. A new engineer and a fresh AI session have the same knowledge gap: they understand general software principles but have no context about the specific choices this project has made. An anchor document that serves one serves both.

Garg’s article frames context anchoring primarily as a tool for maintaining consistency across AI sessions. The discipline of maintaining such a document, and the format that makes it effective for a stateless AI consumer, also produces something that teams find genuinely useful beyond AI-assisted development. Writing for a reader with no memory turns out to impose useful constraints on clarity and specificity that benefit human readers as well. The AI just makes the cost of not writing it more immediate.

Was this interesting?