Part two of Beyond Code Generation, a two-part series on what an agentic software delivery system must understand and enforce. Read part one: Code Is Cheap. Verification Is the New Scarcity.
Ask an agent to add a partner integration to an enterprise system.
It reads the repository, finds an HTTP client, copies the local deployment pattern, adds tests, and opens a clean pull request. Everything passes, except the change violates a decision made three years earlier.
Three years ago, the organisation decided that outbound partner traffic must go through a managed integration layer. The decision followed an incident, a regulatory finding, and two months of argument. It is documented in ADR-017, linked from a wiki page, attached to the minutes of an architecture forum, and visible in a diagram exported as a PNG.
The agent never saw any of it. The repository contained a contradictory example, so it followed the strongest evidence it could reach.
The failure points to a broader architectural problem:
An agent cannot respect a decision it cannot find, connect to the task, and test against the proposed change.
Architecture that is obvious to the organisation may still be unavailable to the delivery system.
The repository already looks like the truth
Humans are surprisingly good at compensating for bad architecture records.
People remember that a diagram is out of date, that the decision marked "proposed" was accepted in the next meeting, and that one service violates the standard because it predates it. When the documents disagree, they message the architect who still remembers why.
An agent sees files, dependencies, schemas, configuration, instructions, tests, tool output, and whatever documentation has been placed within reach. If the approved architecture says one thing and the repository demonstrates another, the repository usually wins.
The agent sees one architecture: the implemented estate. The organisation's approved intent may remain invisible.
That gap creates a nasty feedback loop. Agents learn from the current codebase. They repeat its dominant patterns. Repetition makes those patterns more dominant, including the deprecated and accidental ones. Drift that once spread by copy and paste can now spread at machine speed.
The problem is not whether a model can read a diagram. Even when it can interpret the image, the answer may not be current, scoped, authoritative, or testable.
A picture can be legible and still be useless at the moment of change.
OpenAI's harness engineering account offers a concrete version of this problem. Its team found that knowledge outside the agent's accessible context effectively did not exist, then enforced core dependency directions with custom linters and structural tests. Other teams will implement this differently. The lesson carries: agents need accessible context and enforceable boundaries.
Architecture has three surfaces now
Architecture documentation has always helped people reason about a system. People still need views, narratives, trade-offs, history, and a shared language for decisions.
Agentic delivery also needs context before the agent plans. That includes applicable decisions, allowed relationships, required patterns, ownership, exceptions, and risk boundaries. After the agent proposes a change, the delivery system needs controls for dependency rules, interface policies, infrastructure constraints, data boundaries, and required evidence.
The three surfaces serve different jobs:
| Surface | Core question | Best form |
|---|---|---|
| Narrative | Why did we choose this, and what trade-off did we accept? | ADR, design note, review record |
| Model | What exists, how is it related, and where does the decision apply? | Addressable architecture model |
| Check | Does this proposed or deployed state violate a testable consequence? | Fitness function, policy, contract test, runtime query |
Using one artefact for all three jobs causes trouble. A policy with no rationale becomes arbitrary. An ADR with no scope becomes hard to retrieve. A model with no conformance check becomes a nicer picture of intent. The three artefacts work when the system connects them.
A diagram is a view, not a decision
The C4 model gives architecture a practical vocabulary of software systems, containers, components, code, and the diagrams that show them at different levels.
Text-based tools such as Structurizr DSL and LikeC4 make the underlying structure addressable. Elements, relationships, boundaries, and views can live in Git. A change can be reviewed as text, validated in CI, rendered for people, and queried by tools.
A PNG gives an agent pixels and labels. A model gives it stable identities, types, hierarchy, relationships, tags, metadata, and scope. It becomes possible to ask which services handle restricted data, what depends on a component, or whether a proposed connection crosses a trust boundary.
Architecture-as-code makes architecture addressable, though the model can still be wrong.
Addressability is the first requirement for machine context. It is not yet governance.
ADRs contain the part the model cannot
A model can say that the customer API calls the identity service. The Architecture Decision Record explains why that relationship was chosen, which alternatives were rejected, what assumptions mattered, and which consequence the organisation agreed to carry.
Formats such as MADR deliberately keep the human record lightweight: context, options, decision, and consequences. Nobody needs a generation of agents producing forty-page ADRs that nobody will read.
But a folder of thoughtful Markdown files is still only a folder. For an agent to use a decision, the surrounding system needs a small amount of structure:
- a stable identifier and status;
- an owner and decision authority;
- the systems, components, repositories, interfaces, or data domains in scope;
- related, conflicting, and superseding decisions;
- effective and expiry dates where they matter;
- whether each consequence is advisory or enforced;
- the checks that provide evidence of conformance;
- approved exceptions, their owners, and their expiry.
An illustrative header might look like this:
---
id: ADR-PAYMENTS-042
status: accepted
title: Route public payment APIs through the managed gateway
owner: payments-architecture
applies_to:
components:
- payments.customer_api
- payments.partner_api
repositories:
- payments-api
constraints:
- id: ARCH-042-01
mode: enforced
policy: policies/public-api-through-gateway.rego
supersedes:
- ADR-PAYMENTS-019
---
Different organisations will need different fields. The purpose of the schema is to connect a human decision to the parts of the system it governs and the evidence that can assess it.
That connection turns historical explanation into usable delivery context.
Applicability beats document retrieval
Suppose an agent finds five ADRs about public APIs: one enterprise principle, two domain decisions, a rejected proposal, and an accepted record later superseded by another. A vector search can return all five with impressive semantic relevance and still leave the agent with the wrong instruction.
Search can retrieve candidates. It cannot resolve which decision applies.
The agent needs the answer to a narrower question:
For this component, repository, interface, environment, and date, which decisions are in force?
That requires status, scope, inheritance, supersession, and exceptions. It also requires provenance. The agent should be able to say why a decision applies and where the answer came from.
Many architecture knowledge projects fail here. They optimise document ingestion and call the result context. More context is not necessarily better. An uncontrolled dump of stale decisions can be worse than no context because it gives contradiction an air of authority.
Resolve the smallest trustworthy set of documents that governs the task instead of making every architecture document available to every agent.
Keep approved, proposed, and observed architecture separate
| State | What it represents | Who or what may change it |
|---|---|---|
| Approved | The design and constraints the organisation currently authorises | Accountable decision authority |
| Proposed | The architecture implied by the change under review | Team or implementation agent |
| Observed | The relationships and resources that exist at runtime | Discovery, inventory, traces, deployment state |
These states should inform one another, but they must not silently collapse.
An agent may propose a new relationship, but approval stays with the accountable authority. Runtime discovery may observe communication between two services without establishing that the communication is legitimate. An approved path through a gateway is also no proof that production still follows it.
Keeping the three states distinct turns drift into a useful signal:
- proposed differs from approved: review the design or request an exception;
- observed differs from approved: investigate runtime drift;
- observed differs from proposed after deployment: the release did not create the state it claimed;
- approved repeatedly differs from reality: revisit the decision instead of normalising the violation.
Architecture still mediates between intent and reality. The differences between these states turn drift into evidence that a team can investigate.
From decision to constraint
Reserve gates for testable constraints. Decisions about vendor strategy, organisational boundaries, acceptable complexity, or future flexibility still require judgment. Encoding every preference as policy would calcify the system and teach teams to work around it.
But many consequences are testable.
Take the decision that public APIs must enter through an approved gateway using the organisation's current transport-security baseline. The evidence chain might work like this:
- The ADR explains the incident, trade-off, decision, and exception authority.
- The architecture model identifies public interfaces, gateways, services, trust boundaries, and allowed relationships.
- Delivery checks inspect the proposed model, API specification, Terraform plan, and gateway configuration.
- Runtime checks confirm the deployed endpoint, protocol configuration, and observed traffic path.
Each link protects against a different failure.
- The ADR keeps the policy from becoming unexplained bureaucracy.
- The model gives the rule scope.
- The delivery checks catch a bad change before release.
- Runtime evidence catches drift and false confidence after it.
The chain brings architecture into the verification system without pretending that every architectural question has a boolean answer.
Put the architecture diff beside the code diff
An agent planning a meaningful change should not start with repository search alone. It should first be able to ask:
I am changing payments.customer_api to call a fraud provider. Show the active decisions, permitted outbound relationships, data classifications, platform requirements, exceptions, and owners that apply.The agent can then propose two connected changes:
- the implementation diff;
- the architecture diff: new or changed elements, relationships, data flows, and decisions.
The platform evaluates both. Does the new dependency cross a forbidden boundary? Does a public endpoint bypass the gateway? Is restricted data leaving an approved region? Is a synchronous call being introduced where an active ADR requires events? Does the new component have an owner and operational tier?
The platform should return feedback the agent can act on, rather than a generic red gate:
ARCH-042-01failed.external.partnernow callspayments.partner_apidirectly. ADR-PAYMENTS-042 requires public traffic to enter throughshared.managed_gateway. Change the model and implementation, or request an exception frompayments-architecture.
That message contains the violated rule, the evidence, the governing decision, the expected repair, and the escalation path. A human benefits from the same clarity.
Architecture review moves from a late meeting to a source of context inside the delivery loop. The meeting remains for the decision that actually needs one.
A control plane can start small
The phrase "architecture control plane" sounds like a procurement programme. Its first useful version may be a script, some metadata, and existing delivery tools.
The organisation needs a few capabilities assembled from repositories, architecture tooling, CI, policy engines, service catalogues, and runtime inventory:
| Capability | Minimum useful behaviour |
|---|---|
| Resolve | Return the effective decisions for a change, including supersession and exceptions |
| Query | Find model elements, owners, dependencies, boundaries, and classifications by stable identity |
| Check | Select and run relevant fitness functions against proposed and deployed state |
| Explain | Return actionable failures with rationale and provenance |
| Escalate | Route exceptions or new decisions to an accountable authority |
| Trace | Link task, decision, change, approval, deployment, and conformance evidence |
Tools such as ArchUnit can test language-level dependency rules. Architecture models can validate required metadata and allowed relationships. API and event specifications can be checked against contracts. Infrastructure plans can be checked for networking, encryption, and resilience patterns. Open Policy Agent can apply organisation-specific policy-as-code to structured CI/CD inputs. Runtime inventory and traces can expose what actually happened.
No one tool understands the architecture automatically. The coordination layer supplies the meaning: which decision exists, where it applies, what evidence to gather, and who may override it.
If the result is another dashboard architects admire while delivery ignores it, the control plane has failed.
Four ways this goes wrong
Making architecture machine-legible creates failure modes that deserve explicit design.
The context swamp
Every document is indexed and injected. The agent receives stale principles, local exceptions, rejected proposals, and duplicated standards. Retrieval looks sophisticated; applicability remains unsolved.
The shadow model
Teams update the code but not the architecture, so the model becomes theatre. Or they update the model mechanically to match every implementation, turning description into accidental approval.
Policy calcification
A constraint survives long after the assumptions behind it expire. The check stays green, the organisation feels governed, and the architecture becomes an obstacle to the business.
Self-approval
The implementation agent changes the code, weakens the policy, marks the ADR superseded, and declares success in one pull request. Every file is consistent. The separation of authority has vanished.
The remedies are ownership, freshness checks, explicit lifecycle, protected rules, independent review for decisions and exceptions, and runtime comparison. Architecture-as-code only creates the conditions for governance.
Start with one scar
Choose one decision that exists because the organisation learned something expensive: public traffic through the gateway, restricted data encrypted with approved keys, domain packages isolated from infrastructure packages, production workloads emitting standard telemetry, or services publishing only to declared event contracts.
Then close one loop:
- Record the rationale, authority, scope, and exception path in an ADR.
- Give the affected systems and components stable identities in the architecture model.
- Encode one testable consequence as a fitness function or policy.
- Run the check in advisory mode and study false positives before making it a gate.
- Return a structured failure that tells an agent or engineer what to do next.
- Compare the approved claim with runtime evidence where that evidence exists.
- Review whether the rule is still useful after teams have lived with it.
Working through one real decision will teach more than modelling the whole enterprise in the abstract. It will expose inconsistent names, missing owners, ambiguous scope, invisible exceptions, and policies that cannot explain themselves. Those gaps are the actual state of the architecture, now visible.
The architecture function moves into the loop
In a human-paced SDLC, architecture could operate through periodic review. Teams brought a design. Architects examined it. Decisions were recorded, or merely remembered. Drift accumulated slowly enough for governance to pretend it would catch up later.
Agents change the volume and speed of proposed change. A monthly forum cannot be the primary mechanism for keeping hundreds of machine-generated changes aligned.
Architecture has to move earlier:
- decisions exposed before the agent plans;
- models changed beside the implementation;
- testable consequences evaluated during the loop;
- exceptions routed to the right people;
- runtime drift returned as evidence;
- repeated review comments converted into reusable checks.
Automating routine conformance leaves architects more time for trade-offs, exceptions, and decisions that cannot be compiled.
The architect's job is to design and evolve the decision system within which generation happens, rather than review every generated line.
Make the invisible operational
Part one argued that code generation is becoming an intermediate detail. The useful capability is defining an outcome and gathering enough independent evidence to know whether it happened.
Architecture belongs in that evidence.
But "respects the architecture" cannot remain a sentence in a definition of done. It must resolve to current decisions, addressable models, applicable constraints, explicit exceptions, and accountable judgment.
A prettier diagram will not help. The agent needs to know which world it is allowed to create, why those boundaries exist, and when it must stop and ask.
Until an organisation can express that world in a form the delivery system can find, scope, and test, its architecture is not governing agentic development. It is watching from the document repository.
The Conversation
Members can comment on every field note.
Subscribe to join the discussion and add your perspective to the record.