Architecture-Aware Agentic Development

Architecture-Aware Agentic Development

AI coding agents are becoming very good at implementing requirements, writing tests, refactoring code, and working across an entire repository. But implementing a requirement correctly and preserving the architecture are not the same thing.

An agent can produce perfectly reasonable code that solves the immediate task while silently changing dependency direction, introducing a new responsibility, bypassing an application boundary, or creating a second architectural pattern next to the one that already exists. The code can compile. The tests can pass. The feature can work. The architecture can still drift.

This article describes an experiment in making architecture an active part of agentic development rather than passive documentation. The approach combines a small project-specific Architecture Definition Language (ADL), ordinary architecture documentation, targeted agent guidance, architecture-impact analysis, and executable architecture fitness functions.

The goal is deliberately modest: not to create a new universal architecture framework, but to make the architectural rules of a repository explicit enough that both humans and coding agents can reason about them, while keeping the context small.

Core idea: requirements say what is wanted; architecture explains why the system is structured in a certain way; ADL states what must remain true; guides and skills help the agent work within those constraints; tests provide independent evidence.

1. The Problem: Correct Code Can Still Be Architecturally Wrong

Consider a desktop system resource explorer. A requirement asks for GPU information. A coding agent may reasonably discover a GPU library and call it directly from the UI:

UI -> GPU library

The result may be functionally correct. But the intended architecture may require all system collection to go through a dedicated analyzer and application boundary:

UI -> Application -> Domain
                     ^
                     |
                  Analyzer -> OS / device API

The requirement itself does not necessarily contain this information, and it should not. Product requirements and architecture have different responsibilities.

Traditional architecture documentation helps, but it has two weaknesses in an agentic workflow. First, it is often descriptive rather than explicit about constraints. Second, loading large architecture documents into every agent interaction is expensive and creates noise. The agent needs the right architectural context, not necessarily all architectural context.

This led me to a simple question:

Can architectural intent be represented compactly enough for an agent to use during implementation, while still remaining understandable and maintainable by humans?

2. Separate the Responsibilities Before Adding More Automation

The most important part of the approach is not the ADL syntax. It is the separation of concerns between the documents.

Artifact Responsibility
REQUIREMENTS.md What the product should do.
PROJECT_DESIGN.md Why the architecture looks the way it does and where responsibilities belong.
ARCHITECTURE_ADL.md What must remain architecturally true.
ADL_SPEC.md The syntax and semantics of the small architecture language.
NEW_FEATURE_GUIDE.md The procedure for introducing a feature without duplicating architecture rules.
architecture-impact-analysis/SKILL.md A repeatable procedure for comparing a proposed or generated solution with documented architecture.
Technology standards How implementation quality is maintained, for example Python or GitHub Actions practices.
Architecture tests / fitness functions Executable evidence for deterministic architecture constraints.
AGENTS.md The entry point and context router. It tells the agent where to look; it is not architecture authority itself.

This separation prevents a common failure mode: the same architecture rule being independently restated as authoritative in a README, an agent prompt, a coding standard, an architecture document, and a test. The architecture contract owns the rule; tests provide evidence for the parts that can be verified deterministically. When several artifacts compete as sources of architectural truth, they eventually drift apart.


3. From Product Intent to Conformance

The following diagram is the main mental model for the experiment. The center is the development flow. Supporting documents sit next to the stage where they matter.

%%{init: { "theme": "base", "themeVariables": { "fontFamily": "Segoe UI, Arial, sans-serif", "fontSize": "16px", "primaryColor": "#ffffff", "primaryTextColor": "#111827", "primaryBorderColor": "#64748b", "secondaryColor": "#f8fafc", "tertiaryColor": "#f1f5f9", "lineColor": "#475569", "edgeLabelBackground": "#ffffff", "clusterBkg": "#f8fafc", "clusterBorder": "#cbd5e1" }, "flowchart": { "curve": "linear", "nodeSpacing": 42, "rankSpacing": 52, "htmlLabels": true, "subGraphTitleMargin": { "top": 8, "bottom": 22 } } }}%% flowchart TB %% ========================================================= %% ENTRY %% ========================================================= AGENTS["AGENTS.md<br/><b>Start here</b><br/>Routes the agent to relevant guidance"] %% ========================================================= %% 1 - PRODUCT INTENT %% ========================================================= subgraph S1["1 · PRODUCT INTENT"] REQ["REQUIREMENTS.md<br/><b>What should be built?</b>"] end %% ========================================================= %% 2 - ARCHITECTURE BASELINE %% ========================================================= subgraph S2["2 · ARCHITECTURE BASELINE"] direction LR DESIGN["PROJECT_DESIGN.md<br/><b>Why?</b><br/>Responsibilities & rationale"] ADL["ARCHITECTURE_ADL.md<br/><b>What must remain true?</b><br/>Boundaries & invariants"] SPEC["ADL_SPEC.md<br/><b>How to read the ADL?</b><br/>Language semantics"] end %% ========================================================= %% 3 - DESIGN THE CHANGE %% ========================================================= subgraph S3["3 · DESIGN THE CHANGE"] GUIDE["NEW_FEATURE_GUIDE.md<br/><b>How to introduce the change?</b>"] PLAN["Technical Design / Plan"] end %% ========================================================= %% 4 - ARCHITECTURE CHECK %% ========================================================= subgraph S4["4 · ARCHITECTURE CHECK"] CHECK["architecture-impact-analysis<br/><b>Does the proposed solution fit the architecture?</b>"] GATE{"Architecture<br/>conflict?"} DECISION["Architecture Decision<br/>Update architecture only when explicitly approved"] end %% ========================================================= %% 5 - IMPLEMENT %% ========================================================= subgraph S5["5 · IMPLEMENT"] BUILD["Implementation"] end %% Supporting standards intentionally outside main flow PY["PYTHON_STANDARDS.md<br/>Python implementation rules"] GH["GITHUB_ACTIONS_STANDARDS.md<br/>CI/CD rules when applicable"] %% ========================================================= %% 6 - VERIFY %% ========================================================= subgraph S6["6 · VERIFY"] VERIFY["Executable Verification<br/>pytest / architecture fitness functions"] DRIFT["Architecture Drift Analysis<br/>Compare generated solution with architecture"] RESULT["Conformance Evidence"] end %% ========================================================= %% PRIMARY FLOW - ONE CLEAR SPINE %% ========================================================= AGENTS --> REQ REQ --> DESIGN DESIGN --> GUIDE GUIDE --> PLAN PLAN --> CHECK CHECK --> GATE GATE -->|"No"| BUILD GATE -->|"Yes"| DECISION DECISION -->|"Approved change"| DESIGN BUILD --> VERIFY VERIFY --> DRIFT DRIFT --> RESULT %% ========================================================= %% SUPPORTING RELATIONSHIPS %% ========================================================= SPEC -. "defines" .-> ADL ADL -. "constrains" .-> PLAN PY -. "applies to" .-> BUILD GH -. "applies when needed" .-> BUILD

The important property of this flow is that architecture is consulted before implementation and checked again after implementation. Architectural change is possible, but it should be explicit. The implementation should not silently become the new architecture.


4. A Deliberately Small ADL

In this article, ADL means Architecture Definition Language. The primary conceptual inspiration is the lightweight pseudo-language approach described by Mark Richards and Neal Ford for defining and governing architecture and for supporting executable fitness functions. The syntax in this repository is project-specific: it adapts that idea for an agentic development experiment rather than claiming to be a verbatim implementation of an external grammar or standard.

The vocabulary is intentionally small:

ASSERT
ALWAYS
NEVER
ALLOW
IF / THEN
VERIFIED_BY

The language is used to express architectural boundaries and invariants that should remain easy for both humans and agents to interpret.

For example:

ASSERT DEP-008 (UI HAS_NO_DEPENDENCY_ON Analyzers)
VERIFIED_BY tests/architecture/test_dependencies.py::test_ui_does_not_depend_on_concrete_analyzers

This says two different things:

  • Architecture intent: the UI must not depend directly on concrete analyzers.
  • Evidence: there is an executable fitness function responsible for checking that deterministic constraint.

Not every architecture rule is deterministic. A rule such as “do not hide a new architectural responsibility inside an unrelated component” requires semantic analysis. Such rules can be marked for manual verification rather than pretending that a structural test proves them.

NEVER CHG-004 hide a new architectural responsibility inside an unrelated component
VERIFIED_BY MANUAL

The ADL therefore does not replace architecture documentation, design decisions, coding standards, or tests. It provides a compact architecture contract while those artifacts retain their own responsibilities.


5. Architecture-Impact Analysis

The architecture-impact skill is deliberately read-only and business-requirement agnostic. It compares a technical artifact with the documented architecture.

Its inputs can be a proposed design, implementation plan, source tree, code change, or Git diff. It looks for questions such as:

  • Has a new module, component, service, or architectural responsibility appeared?
  • Has dependency direction changed?
  • Is an existing boundary being bypassed?
  • Has a parallel resource-specific implementation stack appeared?
  • Has responsibility moved to a different component?
  • Has verification been weakened?
  • Does the implementation differ semantically from the documented architecture even if imports still look legal?

It intentionally does not answer whether the business requirement is correct, whether the feature is valuable, or whether an architecture change should be approved.

Important: architecture-impact analysis is analysis, not proof. An agent saying “the architecture is conforming” is not a replacement for executable verification where deterministic verification is possible.

6. How the Agent Actually Uses It

The agent does not start by loading every file in the repository. AGENTS.md acts as a small context router.

A typical feature workflow is:

  1. Read the active requirement.
  2. Read the relevant project design and architecture rules.
  3. Read ADL_SPEC.md only if the language semantics are unclear.
  4. Use the feature guide for a new or materially changed capability.
  5. Create a technical design or implementation plan.
  6. Run architecture-impact analysis against that proposal.
  7. Implement using only the technology standards relevant to the change.
  8. Run behavioral and architecture verification.
  9. Run architecture-impact analysis again against the generated solution.

This progressive disclosure is important. A large body of architecture documentation can consume a significant part of an agent's context window. The goal is not to maximize context. The goal is to supply enough authoritative context for the current decision.


7. Verification: Evidence Instead of Agent Self-Reporting

This is where the approach connects naturally with architectural fitness functions.

For deterministic constraints, the model is:

ADL rule
   |
   v
VERIFIED_BY
   |
   v
architecture fitness function
   |
   v
PASS / FAIL / NOT_APPLICABLE

Examples include package dependency direction, forbidden imports, cycles, required repository artifacts, and other structural constraints that can be expressed reliably.

For semantic constraints:

ADL semantic rule
   |
   v
VERIFIED_BY MANUAL
   |
   v
manual architecture review
   ^
   |
architecture-impact analysis
can support the review

The distinction matters because forcing every architecture concern into a test creates false confidence, while treating every constraint as prose creates weak governance. Architecture-impact analysis can prepare findings for semantic review, but it does not itself turn a manual rule into executable proof or architecture approval.

Another important bootstrap rule is that an empty implementation is not proof of conformance. In the starter repository, architecture tests that require product source code are explicitly not applicable before the source exists. They do not silently pass because there is nothing to inspect.


8. What Did I Observe Before and After Introducing ADL?

This is still an experiment, so I do not want to present qualitative observations as statistical evidence. These observations describe changes in the architecture workflow and representation; they are not yet a controlled before-and-after measurement of implementation quality or agent performance.

8.1 Before

  • Architecture guidance was mostly descriptive.
  • Agents could read design documentation, but important rules were not always addressable as explicit constraints.
  • Architecture rationale, implementation guidance, and constraints were easier to mix together.
  • Architectural review happened mainly after code existed.
  • There was a greater risk that a reasonable implementation choice would silently become an architectural change.

8.2 With the Integration

  • Architectural invariants have stable identifiers.
  • A technical design can be compared with architecture before implementation.
  • Deterministic rules can point directly to executable verification.
  • Semantic drift is analyzed separately from structural tests.
  • Architecture changes become explicit decisions rather than incidental implementation details.
  • Agents can load architecture context progressively instead of consuming a large architecture document for every task.

The most interesting question for future experiments is not whether the agent can parse the syntax. The question is whether this structure materially reduces silent architecture drift across repeated changes.


9. How Well Do Agents Understand the ADL?

My early observation is that agents have little difficulty interpreting this kind of notation when it stays small, explicit, and close to concepts already common in software engineering: dependencies, responsibilities, invariants, permissions, and verification.

I am intentionally avoiding a large modelling language. The agent does not need to learn a complete architecture framework before changing one feature. It needs enough information to answer questions such as:

  • Which component owns this responsibility?
  • Which dependencies are allowed?
  • Which dependencies are forbidden?
  • Is this a normal extension of an existing component or a new architectural responsibility?
  • How will this rule be verified?

The ADL is therefore closer to a compact architecture contract than to a comprehensive architecture modelling environment.


10. How Do I Maintain the ADL?

The maintenance rule is simple: implementation changes normally conform to architecture. If a feature reveals a genuine architecture conflict, the conflict is surfaced instead of being hidden in code.

When an architectural change is approved, three things should normally move together:

PROJECT_DESIGN.md
    architecture rationale

        +

ARCHITECTURE_ADL.md
    architectural rule / invariant

        +

fitness functions
    executable verification where practical

This is important because each artifact answers a different question:

  • PROJECT_DESIGN.md explains why.
  • ARCHITECTURE_ADL.md states what must remain true.
  • Fitness functions provide evidence.

The implementation itself should not be allowed to redefine architecture by accident.

Other artifacts change only when their own concern changes. ADL_SPEC.md changes when the language itself changes, not for normal architecture evolution. REQUIREMENTS.md changes when product intent changes. Technology standards change when implementation practices change. This keeps architecture maintenance focused and prevents a routine architecture decision from triggering edits across unrelated documents.


11. Reference Repository and Experiment

The public reference implementation is available at github.com/services-org-pl/architecture-aware-agentic-development. The repository contains the same architecture model described in this article and is intended to make the experiment inspectable rather than leave the idea only as documentation.

The tagged v0.1-bootstrap baseline captures the repository before product implementation exists. It contains requirements, architecture, agent guidance, lightweight public implementation standards, the architecture-impact skill, and architecture fitness infrastructure, but intentionally no product implementation.

The starting prompt is deliberately small:

Implement REQ-001 (Disk Overview) from docs/REQUIREMENTS.md.
Follow AGENTS.md.

The point of keeping the prompt small is to test whether the repository context is sufficient for the agent to discover and preserve the documented architecture, rather than encoding the architecture directly into the task prompt.

At v0.1-bootstrap, the repository is structured as follows:

architecture-aware-agentic-development/
|
|-- AGENTS.md
|-- README.md
|-- LICENSE
|
|-- docs/
|   |-- REQUIREMENTS.md
|   |
|   |-- architecture/
|   |   |-- PROJECT_DESIGN.md
|   |   |-- ARCHITECTURE_ADL.md
|   |   `-- ADL_SPEC.md
|   |
|   |-- guides/
|   |   `-- NEW_FEATURE_GUIDE.md
|   |
|   |-- skills/
|   |   `-- architecture-impact-analysis/
|   |       `-- SKILL.md
|   |
|   `-- standards/
|       |-- PYTHON_STANDARDS.md
|       `-- GITHUB_ACTIONS_STANDARDS.md
|
|-- tests/
|   `-- architecture/
|       |-- test_dependencies.py
|       `-- test_repository_contract.py
|
|-- pyproject.toml
`-- requirements-dev.txt

The repository is intentionally small enough to inspect end to end. The v0.1-bootstrap tag provides a stable baseline containing the architecture and agent context before product code exists. Later implementation revisions can be compared with that baseline to inspect what the agent created, which architecture rules applied, what the executable checks proved, and whether post-implementation architecture analysis detected semantic drift that structural tests could not express.

This is important for the article as well: the repository is not presented as a finished framework. It is a reproducible reference environment for testing the approach and for evolving the architecture model based on observed agent behavior.


12. Inspiration and Related Work

In this article and repository, ADL means Architecture Definition Language. The primary inspiration comes from Mark Richards and Neal Ford's Architecture Definition Language work: a lightweight pseudo-language for defining and governing software architecture and for supporting executable fitness functions.

That is close to the intent of this experiment: keep architectural constraints compact, repository-native, and easy for an agent to consume. The syntax used here is project-specific. I adapted the idea to emphasize responsibility separation, progressive context loading, architecture-impact analysis, and explicit traceability from deterministic architecture rules to executable verification.

The verification side is also influenced by evolutionary architecture and architectural fitness functions: important architectural characteristics should have objective integrity assessments where practical, while semantic constraints still require architectural judgment.

12.1 References


13. Lessons So Far and Next Steps

The most useful result so far is not a new syntax. It is a cleaner separation between product intent, architecture rationale, architecture constraints, development procedure, agent analysis, implementation standards, and verification.

The lightweight ADL gives architectural constraints stable names and a compact representation. The architecture-impact skill gives the agent a repeatable way to compare technical changes with those constraints. Fitness functions provide evidence for the deterministic parts. Human architectural decisions remain necessary where semantics or trade-offs cannot be reduced to a structural test.

The next step is to run the same small implementation experiment repeatedly and collect evidence:

  • Did the agent discover the relevant architecture without additional prompting?
  • Did it create responsibilities in the expected components?
  • Did deterministic architecture tests detect violations?
  • Did semantic analysis identify issues that structural tests could not?
  • Did the agent attempt to weaken verification?
  • How much extra context and prompting was actually required?

Only after repeated experiments would I make stronger claims about whether this approach measurably improves agent performance. For now, I see it as a practical way to make architecture more explicit and more visible inside the development loop.

Working principle:
Requirements say what is wanted. Architecture explains why. ADL says what must remain true. Guides and skills help the agent work within it. Tests provide independent evidence.
Show Comments
AbuseIPDB Contributor Badge LinkedIn Profile