A coding agent with access to your entire repository does not necessarily understand your system better. It may understand less.
Because a large repository may contains obsolete code, and decisions that were never written down. Giving an agent more files increases the amount of text it can inspect, but this does not guarantee it will identify the constraints that matter more.
The better design is a context packet
a small, versioned, machine-readable description of the system. The packet complements source code by recording the contracts and decisions that source code alone may not reveal.
A normal coding request might look simple:
Add retry handling to the payment notification worker.
An agent can find the worker, inspect its dependencies, and produce a patch quickly. But a safe implementation depends on questions that may not be answered in the worker's directory:
The repository may contain clues, but clues are not contracts.
When the agent receives only the ticket and nearby files, it fills the gaps with plausible assumptions. When it receives the entire repository, it has a different problem: the important rule may be surrounded by thousands of irrelevant or contradictory signals.
The gap comes from context design.
AI coding systems have a finite context budget. The deeper concern is signal density: the proportion of useful constraints among all the material an agent must interpret.
Suppose an agent receives 100 files:
The agent can technically read all of them. It still has to decide which rules apply, which code is authoritative, and which behavior is accidental.
More input creates more opportunities for:
The common response is to improve the prompt. But prompts are a weak place to store architecture because they are difficult to version and validate.
The retrieval boundary should answer three questions before content is added to the packet:
This turns context selection into a policy that can be inspected and improved.
A context packet is the minimal scoped input for a single change or workflow. It includes only the necessary context and constraints, built from a dependency graph instead of folder structure.
A useful packet covers these technical layers:
The packet should be versioned and reviewed like code.
It should also remain small enough that an engineer can read it and update it without a separate platform team.
Taking the example of opening a PR titled “Retry payment notifications after provider timeouts.” The agent does not need a second copy of the repository. It needs the small set of facts that determine whether the change is safe.
The context assembler follows the changed worker through its dependency graph and produces a short packet:
change: retry-payment-notifications
owner: payments-platform
intent: Retry provider timeouts without sending a notification twice.
read:
- PaymentNotificationWorker.cs
- PaymentProviderAdapter.cs
- PaymentNotification.v2.schema.json
- ADR-017-provider-retries.md
edit:
- PaymentNotificationWorker.cs
- NotificationReplayTests.cs
must_preserve:
- NotificationId is stable for every delivery attempt.
- The adapter classifies provider failures.
- Dead-letter records include the failure classification.
checks:
- NotificationReplayTests
- DeadLetterContractTests
The agent makes one scoped change using the packet. It can read/edit code and rerun tests, but not change infra or identity. CI/CD runs two checks and rejects the PR if it edits outside edit or lacks evidence.
That is the complete loop:
Each field has a job:
read
supplies relevant implementation and architecture decisions.edit
limits the proposed diff.must_preserve
records behavior that source code may not explain.checks
connects the packet to the delivery pipeline.Keep the packet as a change brief, not as a repository summary.
The assembler starts with the files changed by the pull request and follows declared dependencies outward. A simple graph might look like this:
The graph determines what belongs in the packet. A node is included when it is directly changed, is a dependency of a changed node, or defines an operational contract for that dependency. Unrelated services and historical examples stay outside the retrieval boundary.
The assembler can collect artifacts from controlled sources:
The assembler should rank artifacts by relevance.
A well-organized packet is useful only when it improves engineering outcomes.
Start with four signals:
| Signal | Question |
|---|---|
| Rework | Did the agent need repeated corrections about the same constraint? |
| Boundary violations | Did the proposal touch files or tools outside its declared scope? |
| Evidence coverage | Were the required checks appropriate and actually run? |
| Review effort | Did reviewers spend less time reconstructing system context? |
Owners must update contracts, schemas, and service metadata. This cost is real. It is also preferable to depending on undocumented knowledge that exists only in one engineer's memory.
A packet that is too narrow can create false confidence. Include dependency evidence and make the agent able to request an expanded boundary. Expansion should be logged and, for sensitive boundaries, approved.
Recording packet versions, source revisions, and freshness introduces process overhead. That overhead pays for itself mainly on changes where debugging and rollback are expensive.
A packet can say that an agent may edit a path, but the runtime must enforce it. Never use a prompt or JSON field as the only security boundary.
Engineers still define the contract, decide which behavior is intentional, and accept the tradeoffs. The packet makes that work explicit and reusable.
The value of a context packet lies in helping an agent distinguish governing rules from code that happens to be nearby.
AI-assisted development becomes more reliable when context is designed and maintained as part of the engineering system.