Make Context Discoverable
Expose repo knowledge so the coding agent can find the right rules without flooding the prompt.
Failure pattern
The coding convention exists, but the agent reaches old docs, stale issue comments, or misleading examples first and implements against the wrong project truth.
In mature SaaS repos, the important rule is often not in the file being edited. It may live in an ADR, test helper, feature flag policy, schema comment, runbook, or recent issue. If the harness does not route context, the agent relies on search luck.
Incident: stale onboarding architecture note
Agent task
The agent is asked:
Add a team invitation status banner to onboarding.
The banner should show whether invited teammates have accepted.
Available surface
The repo contains:
| Source | Date | What it says | Authority |
|---|---|---|---|
| ADR-014 | Jan | Invitations are stored on workspace_invites | Historical |
| ADR-029 | May | Invitations moved to membership_events stream | Current |
| Issue thread | May | Banner should use membership event projection | Current task context |
| Old component | Feb | Reads invite count from workspace_invites | Example only |
| Test helper | May | Builds membership events for onboarding tests | Authoritative for tests |
| README | Mar | Mentions legacy invite flow | Stale |
The agent searches “invite onboarding” and finds the old component first.
Bad run
It implements the banner by querying workspace_invites, adds UI state, and writes a test using a legacy factory.
The code compiles. The banner is wrong for new workspaces because production now derives invitation status from membership_events.
Why the harness failed
The repo had the right context, but not a context ladder.
| Missing routing rule | Consequence |
|---|---|
| Source authority | Old component outranked current ADR |
| Freshness | README and ADR-014 were not marked stale |
| Task context | Issue thread was not surfaced before implementation |
| Test source | Agent missed current helper |
| Conflict rule | Agent did not report old/new invite models conflicted |
The agent used a real pattern. It was the wrong pattern.
Why it happens
Codebases accumulate history. Old examples remain because tests still need them, migrations reference them, or legacy customers still use them. A model sees examples as patterns. It does not automatically know which pattern is current.
Larger context windows do not solve this alone. A huge context dump may include both ADRs, both components, and both helpers. Without source priority, the agent may synthesize a hybrid design no human would approve.
Harness principle
Context should be discoverable by authority and claim type.
For coding agents, the harness should answer:
- Where are current architecture decisions?
- Which docs are historical?
- Which test helpers represent current behavior?
- Which issue or ticket defines this task?
- What should happen when examples conflict?
flowchart TD A["Coding task"] --> B["Repo context index"] B --> C["Current ADR"] B --> D["Issue context"] B --> E["Test helper"] C --> F["Implementation plan"] D --> F E --> F B --> G["Stale sources and conflicts"]
Operating practice
Create a small repo context index:
| Claim type | Authoritative source | Supporting source |
|---|---|---|
| Architecture | Current ADR index | Older ADRs as history |
| Feature behavior | Issue or product spec | Existing UI examples |
| Data model | Schema and migration notes | Legacy components |
| Testing pattern | Current test helpers | Old tests as examples |
| Flags and rollout | Feature flag policy | Release notes |
For the banner task, the harnessed context says:
Current invitation source:
- ADR-029 replaces ADR-014.
- Use membership_events projection.
- Test with createMembershipEvent helper.
Stale examples:
- workspace_invites component is legacy and should not guide new code.
Harnessed run
The agent implements the banner against membership_events, uses the current helper, and notes that legacy invite table code was intentionally not reused.
That note matters. It proves the agent saw the conflicting pattern and chose the current one.
Coding-agent example
A coding context file should route, not become an encyclopedia:
| Entry | Points to | Rule |
|---|---|---|
architecture.current | ADR index | New code follows latest accepted ADR |
testing.current | Test helper guide | Prefer current factories over copied fixtures |
schema.current | Schema docs | Validate against migrations |
task.current | Issue or brief | User-visible behavior source |
legacy.patterns | Legacy notes | Use only when task targets legacy flow |
Review artifact
The useful artifact is a context decision log, not a giant paste of every document the agent found.
| Question | Source checked | Result | Decision |
|---|---|---|---|
| Which invite model is current? | docs/architecture/auth.md | Membership event model is canonical | Use membership_events |
| Is the legacy table still active? | docs/legacy/invites.md | Read-only compatibility path | Do not write workspace_invites |
| Which tests define acceptance behavior? | tests/e2e/invite-acceptance.spec.ts | Covers happy path and expired tokens | Add regression here |
| Which route owns redirect logic? | src/routes/invite/[token].ts | Owns acceptance redirect | Patch here before touching dashboard |
This log is small, but it changes the agent’s behavior. It forces the agent to declare which source outranked another source. If a reviewer disagrees, the disagreement is visible. Without it, stale context failures often hide inside plausible code.
A discoverable-context harness also needs names for freshness. “Auth docs” is too vague. “ADR-029 supersedes ADR-014 for invite acceptance” is actionable. The agent should learn to report source age and authority when the task depends on policy, architecture, migrations, or security behavior.
Context rule:
When two sources disagree, prefer the source with the higher authority class.
If authority is equal, prefer the newer source.
If neither is clear, stop and ask for a decision instead of guessing.
This rule keeps the agent from treating context retrieval as trivia collection. The goal is not to read more; the goal is to route the task through the right knowledge.
Common mistakes
The first mistake is telling the agent to “look around” without priority. Search finds relevance, not authority.
The second mistake is deleting old docs too late. If a doc is historical, mark it historical.
The third mistake is assuming current tests always show current architecture. Tests may preserve old behavior.
The fourth mistake is hiding the issue context. The ticket often explains why a nearby pattern is not appropriate.
Practical exercise
Pick one confusing area of a repo. List current ADRs, stale docs, current helpers, legacy examples, and task sources. Then write a context ladder that tells an agent which source wins for each claim type.
Test it with a task where old and new patterns conflict. A good harness makes the agent mention the conflict before coding.
Key takeaways
- Existing code is not automatically current guidance.
- Repo context needs authority and freshness.
- A context index should route the agent before implementation.
- Stale docs should be labeled, not left as traps.
- The agent should explain when it chooses a current pattern over a legacy one.
Further reading / source notes
- Liu et al., “Lost in the Middle” for long-context retrieval risks.
- Model Context Protocol architecture overview for separating resources, tools, and prompts.