← Back to all postssystems /

Layering Context for AI Coding Agents

How to separate global preferences, repository architecture, package rules, and task intent without creating conflicting instructions.

aiagentscontextarchitecture

This is part five of AI Working Agreements. Start with AGENTS.md Is a Communication Protocol for the complete working-agreement structure.

Giving an AI agent more context is not always helpful. Context has to be relevant, current, and scoped to the decision being made.

A single enormous AGENTS.md file can mix personal communication preferences, repository architecture, package-specific commands, temporary workarounds, and task requirements. The agent receives all of it, but it still has to determine which instructions apply.

I separate context into layers.

Four layers answer four questions

The system I use has four practical layers:

1Global agreement How do we work together?
2Repository context How does this system work?
3Package context What is different in this part of the system?
4Task request What outcome do we need now?

Each layer should contain information that remains true for its scope.

Global working agreement

This layer contains durable collaboration preferences:

  • communication style
  • autonomy boundaries
  • question versus instruction behavior
  • planning and course correction
  • validation expectations
  • Git and deployment approval
  • delegation preferences

These rules follow me between repositories because they describe how I want to work.

Repository instructions

The root AGENTS.md describes the project:

  • purpose and architecture
  • framework and runtime
  • important directories
  • data flow
  • build and validation commands
  • generated files
  • repository conventions
  • deployment constraints

This layer should help an agent navigate accurately without turning into a copy of the README.

Package or directory instructions

Nested files describe local differences:

  • package-specific commands
  • a different language or framework
  • local ownership boundaries
  • generated code that must not be edited
  • specialized testing requirements
  • security or performance constraints

The open AGENTS.md format supports nested files, with the closest applicable file taking precedence. GitHub documents similar nearest-file behavior for agent instructions.

Task request

The user request defines the current outcome, constraints, and approval. It should not have to repeat persistent repository facts, but it can override defaults when the task genuinely requires a different approach.

Put information where it changes

A useful rule is: context should live at the narrowest level where it remains consistently true.

"Lead with the answer" belongs globally.

"This repository uses React Router framework mode" belongs at the repository root.

"Run database integration tests for files in this package" belongs inside the database package.

"Do not deploy this change today" belongs in the task.

Placing a rule too high makes it apply where it should not. Placing it too low forces repetition and makes it easy to miss.

Keep architecture useful and navigable

Repository instructions should orient an agent, not attempt to preload the entire codebase.

A concise architecture section can say:

1## Architecture
2
3- Routes live in `app/routes/` and use React Router framework loaders and actions.
4- Shared UI components live in `app/components/`.
5- Server-only content access lives in `app/services/*.server.ts`.
6- Markdown articles are bundled at build time from `app/content/articles/`.
7- `app/root.tsx` owns document metadata, theme initialization, and global layout.

This gives the agent high-value entry points. It still inspects source before changing behavior.

Avoid embedding large source snippets that will drift out of sync. Point to authoritative files and explain relationships that are not obvious from names.

Separate preferences from facts

Instruction files often mix these categories:

1Fact The app runs on Node 24.
2Convention Route loaders own server data access.
3Preference Prefer inferred TypeScript types.
4Boundary Ask before changing migrations.
5Command Run npm run typecheck.

All can be useful, but knowing the category helps resolve conflicts.

A task can intentionally override a preference. It should not casually override a runtime fact. A nested package can override a convention inside its scope. An approval boundary remains in force unless the person with authority explicitly changes it.

You do not need to label every line with its category. Organizing sections around architecture, conventions, validation, and boundaries usually makes the distinction clear.

Let local conventions beat generic preferences

My global agreement includes TypeScript and frontend preferences. Those preferences should not make an agent rewrite an established repository around my default stack.

I state the precedence directly:

1Existing project conventions override general preferences.
2Before introducing a dependency, test framework, or architecture, inspect what
3this repository already uses.

This prevents context intended to improve consistency from doing the opposite.

The same principle applies inside a monorepo. A package using Go's standard tooling should not inherit JavaScript validation commands from a neighboring application. A legacy service may have constraints that a new package does not.

Use nested files for real boundaries

Nested instructions are useful when a directory represents a meaningful change in environment or ownership.

1AGENTS.md
2apps/
3 web/
4 AGENTS.md
5 admin/
6 AGENTS.md
7packages/
8 database/
9 AGENTS.md
10 design-system/
11 AGENTS.md

The root file can describe the monorepo and shared workflow. apps/web/AGENTS.md can document route and browser testing. packages/database/AGENTS.md can require migration approval and integration tests. packages/design-system/AGENTS.md can define accessibility and visual validation.

Do not create a nested file for every folder. Fragmentation makes it difficult to know where behavior comes from. Add one when the local scope has several durable differences worth loading together.

Avoid duplicating the source of truth

If a command is already authoritative in package.json, the instruction file can name when to run it without reproducing its implementation.

If architecture is maintained in a design document, link to that document and summarize only the facts needed for navigation.

If a generated file includes a warning, the instruction can reinforce "do not edit generated output" and point to the generator.

Duplication creates drift. The agent may follow an old command because the instruction sounds more explicit than the current configuration.

I use instruction files as routing context: where to look, which rules apply, and how to verify work. Source and executable configuration remain evidence.

Handle conflicts explicitly

More layers create the possibility of conflicting instructions.

A healthy hierarchy needs a precedence model. A practical version is:

1explicit current request
2 → nearest applicable package instructions
3 → repository instructions
4 → global working agreement

System-level tool constraints still sit outside this project hierarchy.

Not every conflict should be resolved mechanically. If a task asks to skip a required security check or deploy through a prohibited path, the agent should surface the conflict rather than silently selecting the lower line in a list.

The precedence model handles ordinary specialization. Judgment and approval still handle consequential exceptions.

Do not use AGENTS.md for temporary task state

Instruction files are persistent context. Temporary details age quickly:

  • the current branch goal
  • today's incident status
  • a one-time migration sequence
  • a short-lived feature flag
  • an option that has not been decided

Those belong in the task, issue, runbook, or decision record.

A temporary workaround can belong in AGENTS.md when agents will repeatedly encounter it, but it should include the condition and removal trigger:

1- Until issue #482 is resolved, run integration tests serially because the
2 shared fixture is not concurrency-safe. Remove this instruction with the fix.

Without that lifecycle, temporary context becomes permanent folklore.

Protect sensitive context

Instruction files are usually committed to the repository. Do not place secrets, credentials, private customer data, or sensitive operational details inside them.

Tell the agent where secure configuration comes from and which commands require it, without including the values:

1- Local integration tests read credentials from `.env.test.local`.
2- Never print or commit environment values.
3- Ask before accessing production systems.

Context should make the safe path easier, not expand the amount of sensitive data available to every session.

A layered example

A task to change article publication behavior might resolve context like this:

1Global
2 Questions are read-only.
3 Ask before deployment.
4 Run focused validation.
5
6Repository
7 Articles are bundled Markdown.
8 Routes use React Router loaders.
9 Run typecheck, lint, and production build.
10
11Content directory
12 Front matter dates must be ISO values.
13 Future articles must not appear before their publication timestamp.
14
15Task
16 Schedule five articles for consecutive days.
17 Commit the overview first, but do not deploy yet.

Each layer contributes something different. None needs to restate the others.

A compact layering policy

1## Instruction scope
2
3- Global instructions define durable collaboration preferences.
4- The repository AGENTS.md defines project architecture and shared commands.
5- Add nested AGENTS.md files only for meaningful package-level differences.
6- The nearest applicable project instructions take precedence.
7- Explicit task requirements can override defaults but not hidden safety or
8 approval boundaries.
9- Keep temporary state in tasks, issues, or runbooks rather than permanent
10 instruction files.
11- Point to authoritative source instead of duplicating large configurations.

The goal is not to maximize context. It is to make the right context available at the point where it changes a decision.

A well-layered system helps an agent begin with useful orientation, inspect the correct source, and avoid carrying one part of a codebase's assumptions into another. That is more valuable than giving it every document at once.

Resources