Skip section navigation

Principle 04 / 09

Architecture enables bounded understanding

On this page

A good contract lets an engineer—or an agent—work on one capability without needing the internals of everything around it.

The problem

The difficulty of changing a system is not just its size. It is how much of that system someone must hold in mind to make a safe change. When responsibilities are tangled, a small feature may require understanding storage, security, business rules, messaging, interfaces and unrelated workflows.

This problem becomes conspicuous with AI agents. Loading the entire repository into context is costly and noisy. Supplying a fragment without its real dependencies is risky. The answer is not simply better summarisation; it is better boundaries.

How boundaries reduce context

Separate capabilities by responsibility and expose behavioural contracts. A consumer should know what an operation does, what inputs it accepts, what failures it reports, what it guarantees and what invariants must be preserved. It should not need to know how the provider stores data or which library it uses.

A common pattern is to separate:

  1. Stable mechanics or infrastructure capabilities.
  2. Integrations that combine those mechanics into useful services.
  3. Product-specific orchestration that expresses the business rules or user experience.

This is one possible architecture, not a required number of layers. The test is whether dependencies and responsibilities are intentional.

With stable contracts, work can be divided safely. The change agent receives the consumer-facing contract and the component it is changing; contract tests verify its assumptions. If a contract needs to change, that is elevated to an architectural decision.

Illustrative example

A reporting feature needs maintenance-request status. If a request store exposes get_request(id) and guarantees a documented set of states and version semantics, the reporting component does not need to know SQL tables or write paths. The request store can later be refactored without rewriting reports if the contract remains valid.

This also supports faster product experimentation. New orchestration can assemble existing capabilities rather than repeatedly rebuilding storage and notification systems.

What to verify

  • Dependency direction and forbidden imports.
  • Schema compatibility, error semantics and behavioural invariants.
  • Contract tests run from the consumer’s point of view.
  • Integration tests at boundaries that matter.

Limits

Too many layers and abstractions can be worse than a straightforward module. Contracts that specify only types but omit meaningful semantics create false confidence. Some product decisions legitimately cross boundaries; those changes need a broader context and deliberate coordination. The goal is the smallest sufficient context, not artificial isolation.

See the worked example: layered architecture, contracts, and the executable intake slice.

Relay product orchestration composes intake and assignment through request storage, audit and notification contracts. Development tools check the boundaries.
One possible set of boundaries for the fictional Relay example. Assignment and production adapters remain design targets.

Consulting

Need help with the work?

We can review a design, help set up an AI-assisted workflow or work with your team on implementation.