· 8 min read ·

Decisions Made 30 Messages Ago: Context Anchoring and the Second Half of the Context Problem

Source: martinfowler

You are thirty messages into a session. Early on you and the model agreed: this refactor uses the repository pattern, not the service locator. You explained why, the model acknowledged it, and the next several responses reflected that choice correctly. Then the context window filled up with implementation details, follow-up questions, and tool outputs. Now the model is generating a service locator. It has not forgotten what you said in any literal sense, it is still in the transcript. It has just stopped paying attention to it.

This is a different problem from the one that CLAUDE.md and knowledge priming solve, and conflating them is why many teams feel like they have sorted out context management and still hit this failure mode.

Two Halves of the Same Problem

Knowledge priming addresses what the model knows about your project before a session begins. You write down architectural constraints, prohibited patterns, and non-obvious conventions. The model reads them at session start and applies them throughout. The information is static; it describes the project as it exists, not the decisions you are about to make.

That is the first half. The second half is everything that gets decided during the session itself. Which approach to take for this specific task. What constraints were negotiated mid-conversation. Which options were explicitly ruled out and why. This is where knowledge priming ends and where Context Anchoring, described by Rahul Garg as part of Martin Fowler’s Reducing Friction with AI series, picks up.

A context anchor is a living document, typically a markdown file, that you maintain alongside the conversation. It captures decisions as they are made and gets referenced explicitly throughout the session so the model always knows where the current state of the design stands.

Why Decisions Decay

The transformer attention mechanism does not weight all positions in a context window equally. Models trained on long sequences develop a pronounced recency bias: information near the end of the context, where the most recent messages sit, exerts more influence on what gets generated next than information that appeared earlier. This is well-understood behavior and not specific to any one model.

The Lost in the Middle paper from Liu et al. at Stanford and UC Berkeley made this concrete in 2023. The researchers tested language models on multi-document question answering tasks where the relevant document was placed at different positions in a long context. Performance degraded significantly for documents placed in the middle of the context, compared to those placed at the beginning or end. The effect was robust across model sizes and context lengths.

Applied to a long coding session, this means a decision made at message five is sitting somewhere in the middle of a sixty-message context by the time you are implementing message fifty. The model has not discarded it, but its influence on generation has weakened considerably. The model defaults toward whatever is most salient recently, which is the implementation details from the last ten exchanges, not the architectural choice you locked in at the start.

New sessions make this total. Whatever was decided before has no representation at all unless you bring it back explicitly. If you close the session and return tomorrow, you are starting from scratch on everything that was negotiated mid-conversation, even if your CLAUDE.md describes the project correctly.

What a Context Anchor Looks Like

The format is deliberately simple. A context anchor is a markdown file you create at the start of a session and update as decisions are made. The model is pointed to it at session start and re-referenced when significant decisions occur. Here is a representative example:

# Session Context: Payment Flow Refactor

## Objective
Refactor the checkout payment flow to use the repository pattern,
removing direct database calls from the payment service layer.

## Decisions Made

### Architecture
- Using the repository pattern (not service locator)
  - Rationale: service locator was rejected because it obscures dependencies
    and makes the payment service harder to test in isolation
- Repositories live in /src/repositories, injected via constructor

### Scope
- This session covers PaymentRepository and OrderRepository only
- SubscriptionRepository is out of scope (different team owns it)
- No schema changes in this session; data model is fixed

### Constraints
- Do not introduce a DI framework; manual constructor injection is fine
  for the current codebase size
- All repository interfaces must be typed with explicit return types;
  no implicit `any`

## Open Questions
- Whether to wrap repository errors in domain exceptions or let them
  surface as-is to the service layer (deferred, not yet decided)

## References
- CLAUDE.md: /CLAUDE.md (project conventions)
- Existing payment service: /src/services/PaymentService.ts

The key structural feature is the Decisions Made section with rationale. Not just what was decided, but why the alternatives were rejected. This matters for the same reason it matters in knowledge priming: a model that understands the reasoning behind a constraint generalizes it correctly to adjacent cases. A model that only sees the conclusion produces correct output in cases the constraint directly addresses and plausible but wrong output in cases it does not explicitly cover.

The Open Questions section is equally important. Unanswered questions left implicit will be answered by the model, implicitly, in whatever way seems most reasonable given the current context. Making them explicit prevents the model from making choices that look like implementation details but are actually design decisions.

This Is Not CLAUDE.md

The distinction is worth being precise about because the documents look superficially similar.

CLAUDE.md describes the project. It lists conventions that apply across all sessions. It is maintained as part of the codebase, reviewed in pull requests, updated when architecture changes. Its contents are stable across months. It is designed to be read once at session start.

A context anchor describes this session. It captures decisions specific to the current task. It lives for the duration of the session and then becomes reference material for the next developer who touches the same area. Its contents change during the session as decisions are made and scope is refined. It should be re-read, or at minimum re-referenced, at significant decision points during the session, not just once at the beginning.

The position argument from the Lost in the Middle work applies here too. Referencing the anchor document explicitly, by asking the model to check the current state of decisions before generating something significant, pulls it back to the beginning of attention rather than letting it drift into the middle. The explicit reference is not just good hygiene; it is working with the mechanics of how transformer attention operates over long sequences.

The ADR Parallel

Software teams have a long-established pattern for capturing design decisions: Architecture Decision Records, or ADRs, introduced by Michael Nygard and popularized through tooling like adr-tools. An ADR captures a single architectural decision, the context that led to it, the options that were considered, the decision that was made, and the consequences expected from it.

A context anchor is essentially an ADR you are writing in real time, during an AI session, before the decision has hardened into code. The parallels are direct. Context replaces the background context section of an ADR. Decisions Made replaces the decision section. Rationale recorded for each choice maps to the consequences and rejected alternatives sections. The session anchor externalizes what would otherwise be conversational and ephemeral into a document with the same structure that ADRs have used for years.

This framing is useful because it grounds context anchoring in an existing software discipline. Teams already know how to write ADRs, how to review them, and how to treat them as living documentation. Extending that practice into AI sessions requires learning no new concepts, only applying existing ones to a new artifact. The anchor documents from a complex refactor also make natural starting points for permanent ADRs once the session is complete. The rationale is already written; it just needs to move from session artifact to project record.

The Maintenance Problem

The honest difficulty with context anchoring is that someone has to maintain the document during the session. Decisions need to be recorded as they are made, not reconstructed afterward. Open questions need to be promoted to decisions once they are resolved. Scope changes need to be reflected.

This is not zero effort, and the effort arrives exactly when you are in the middle of building something and most reluctant to stop and write documentation. The temptation is to keep going and update the anchor later, which leads to an anchor that is never updated.

The practical approaches are imperfect. You can periodically ask the model to update the anchor document itself, giving it the current state of the conversation and asking it to reflect the decisions made so far. This works reasonably well for straightforward sessions where the decisions are clear. For complex sessions involving significant ambiguity or back-and-forth, the model’s summary of what was decided can be incomplete or slightly off. You end up reviewing its update rather than writing it from scratch, which is faster but still requires attention.

Some teams make the update explicit at decision points rather than periodic: whenever a significant design question is resolved, the next message asks the model to record the decision in the anchor before continuing. This catches decisions as they happen rather than trying to reconstruct them later. The overhead is a pause every few decisions, which is a reasonable trade-off for sessions where the decisions are consequential.

Where This Is Going

The current state requires manual discipline. Future tooling could automate meaningful portions of it.

An AI coding tool that tracked decisions made during a session, prompted you to confirm them before recording, and automatically structured them into an anchor document would remove most of the maintenance burden. The model already has access to the full conversation transcript; identifying the moments where a design decision was made and extracting the rationale is a tractable task. Several tools are beginning to move in this direction with session summaries and handoff documents, though the decision-specific structure of a context anchor is not yet standard.

Longer-context models reduce the severity of the decay problem without eliminating it. A one-million-token context window still has recency bias. The positions in the middle of a very long context are still disadvantaged relative to the beginning and end. More context buys you more conversation before the decay problem becomes acute, but it does not make the problem go away, and it introduces its own cost and latency tradeoffs.

The more durable solution is the document itself. A well-maintained context anchor survives context window limits, survives session restarts, and survives handing the task to a different developer with a different tool. It converts what is otherwise a transient artifact, the negotiated understanding inside a single conversation, into something that can be re-injected into any subsequent session with the same fidelity as the first.

Knowledge priming tells the model what your project is. Context anchoring tells the model what you decided this session. Both are necessary, and the second remains meaningfully underused compared to the first.

Was this interesting?