An example demonstrating how to develop software in the agentic AI age across three layers: Architecture as Code (AaC) · Spec-Driven Development (SDD) · Agentic AI implementation—all as plain text, version-controlled, and AI-readable. AaC itself rests on four pillars: ADRs, C4 views, domain models, and IaC specs.
📖 Full Documentation: See the Architecture Hub for a complete overview of all architectural artifacts.
This repository accompanies this article series:
| # | Article | Description |
|---|---|---|
| 1 | Keep Your Architecture Diagrams in Code, Not in Tools | Why and how to store diagrams as plain text in your repo |
| 2 | Keep Your AI and Architecture/Design in Sync | Spec-driven development so AI agents respect your architecture |
| 3 | Architecture as Code in Practice | ADRs, C4 diagrams, and domain models working together |
| 4 | Think in Specs — The Modern Developer's Mindset | The mindset that ties architecture, design, and agentic AI together |
| 5 | Spec-Driven Test Strategy — Turning Acceptance Criteria into Tests | How AC IDs, test types, and coverage rules turn specs into executable proof |
- 🎯 What This Repository Demonstrates
- 📂 Repository Structure
- 🏗️ The Complete Workflow
- 📚 Documentation Structure
- 🔄 OpenSpec Integration
- 📖 Real Examples
- 🛠️ Using This Repository
- 📝 Making Changes
- 📚 Related Resources
- 🤝 Contributing
- 🚀 Get Started
Software development still moves through three layers — AI changes who does the implementation, not the layers themselves:
| Layer | Practice | What lives here |
|---|---|---|
| 🏛️ Architecture | Architecture as Code (AaC) | ADRs, C4 diagrams, domain models, flows, IaC specs |
| 📋 Design | Spec-Driven Development (SDD) | Change proposals, specs, tasks |
| ⚙️ Implementation | Agentic AI | Code — written by the AI from the spec |
Key insight: AI is excellent at implementation. Humans are still required for architecture and design. See the article series for the full mindset behind this approach.
architecture/
├── adr/ # WHY: Architecture Decision Records
│ └── 0001-use-uuid-primary-keys.md
├── c4-views/ # WHAT: System structure at multiple zoom levels
│ └── system-context.md
├── models/ # HOW: Domain entities and business flows
│ ├── domain/order.md
│ └── flows/create-order.md
└── iac/ # WHERE/GUARDRAILS: Infrastructure specs and environment policy
├── networking.md
├── iam.md
└── environments.md
ADRs document why decisions were made, C4 diagrams show what the system looks like, domain models explain how entities relate and workflows execute, and IaC specs define where the system runs and what guardrails govern it.
| Category | Link | Description |
|---|---|---|
| ADRs | architecture/adr/ | Architecture Decision Records (MADR format) |
| C4 Views | architecture/c4-views/ | System diagrams at multiple zoom levels |
| Domain Models | architecture/models/ | Entity and workflow documentation |
| IaC Specs | architecture/iac/ | Networking, IAM, and environment guardrails |
| Specifications | openspec/ | Detailed behavior specifications |
| User Stories | docs/user-stories/ | Feature backlog |
| AI Guidelines | AGENTS.md | Guidelines for AI agents |
├── .articles/ # 📰 Article series (read-only reference)
├── .github/ # GitHub Actions and workflows
├── .tools/ # Development tooling and scripts
├── AGENTS.md # AI agent guidelines
├── CONTRIBUTING.md # Contribution guidelines
├── architecture/ # ⭐ Core: Four-pillar architecture documentation
│ ├── adr/ # Architecture Decision Records (WHY)
│ │ ├── 0001-use-uuid-primary-keys.md
│ │ ├── 0002-microservices-architecture.md
│ │ └── 0003-event-driven-communication.md
│ ├── c4-views/ # C4 Model diagrams (WHAT)
│ │ ├── structurizr-dsl/ # DSL source files
│ │ ├── images/ # Generated SVG diagrams
│ │ ├── system-context.md
│ │ ├── container.md
│ │ ├── order-service-component.md
│ │ └── payment-service-component.md
│ ├── models/ # Domain models and flows (HOW)
│ │ ├── domain/ # Entity diagrams
│ │ │ ├── customer.md
│ │ │ ├── order.md
│ │ │ ├── product.md
│ │ │ └── payment.md
│ │ └── flows/ # Business workflows
│ │ ├── create-order.md
│ │ ├── payment-processing.md
│ │ └── inventory-management.md
│ └── iac/ # Infrastructure specs (WHERE/GUARDRAILS)
│ ├── networking.md # VPC topology and security groups
│ ├── iam.md # Per-service roles and least-privilege policies
│ └── environments.md # Dev / staging / prod guardrails
├── docs/ # Additional documentation
│ ├── requirements.md
│ └── user-stories/
├── openspec/ # Specifications (OpenSpec structure)
│ ├── specs/ # Source of truth specifications
│ └── changes/ # Active and archived change proposals
├── screenshots/ # Visual documentation assets
├── src/ # Application code
└── tests/ # Test suites
AaC + SDD + Agentic AI form a closed loop — the mono-repo is the single source of truth:
graph TD
AaC["🏛️ Architecture as Code<br>ADRs · C4 · Domain models · IaC specs"]
SDD["📋 Spec-Driven Development<br>Change proposals · Specs · Tasks"]
AI["⚙️ Agentic AI<br>Implementation · Archiving"]
Repo["📜 Mono-repo<br>Single source of truth"]
Repo --> AaC
Repo --> SDD
AaC -->|"Context & constraints"| SDD
SDD -->|"Intent & tasks"| AI
AI -->|"Archived delta"| Repo
ADRs capture the context, alternatives, and rationale behind architectural decisions. Six months from now, when someone asks "Why did we choose UUIDs instead of auto-increment IDs?", the answer is in an ADR—not lost in Slack.
Example: ADR-0001: Use UUID Primary Keys
Each ADR includes: decision status, context, options considered with trade-offs, decision rationale, and consequences.
Format: MADR (Markdown ADR) for consistency and AI-readability.
C4 diagrams show the system structure at multiple zoom levels:
- Level 1: System Context — The system, its users, and external dependencies
- Level 2: Container View — Major services, databases, and communication
- Level 3: Component Views — Internal structure of specific services
Format: Structurizr DSL—plain text with C4-native semantics.
Domain Entities: Customer · Order · Product · Payment
Business Flows: Create Order · Payment Processing · Inventory Management
Format: Mermaid—embeds directly in Markdown, renders everywhere.
IaC files are not just automation scripts — they are version-controlled contracts for your environment. Treating them as specs means they live in the repo alongside ADRs and C4 diagrams, and can be reviewed, linted, and enforced before anything hits a pipeline. See Microsoft: What is Infrastructure as Code?.
- Networking — VPC topology, subnets, and per-service security-group rules
- IAM — Per-service roles, least-privilege policies, and RabbitMQ permissions
- Environments — Dev / staging / prod definitions and promotion guardrails
Format: Markdown specs (cloud-agnostic) — acts as the human-readable contract that Terraform / Bicep / Pulumi files implement.
- Architecture Hub — Start here for the complete architecture overview
- Requirements — Functional and non-functional requirements
- User Stories — Feature backlog with acceptance criteria
New to the project? System Context → Container View → ADR-0002: Microservices
Want to understand a feature? Create Order Flow → Order Model → Related ADRs
Looking for past decisions? Browse the ADR index
Deploying or reviewing infra? Networking → IAM → Environments
OpenSpec complements AaC with Spec-Driven Development: write a change proposal before any code is written, let an AI implement task by task from the spec, then archive the delta back into the specs. The workflow is deliberately front-loaded — design issues surface when they are inexpensive to fix.
| Component | Purpose | Examples |
|---|---|---|
| Architecture | System structure, decisions, and design | ADRs, C4 diagrams, domain models, IaC specs |
| OpenSpec | Detailed behavior specs and change management | Change proposals, business rules, validation logic |
/openspec/specs/— Source-of-truth specifications per domain/openspec/changes/— Active and archived change proposals (proposal.md,tasks.md, spec deltas)- AGENTS.md — Guidelines for AI agents working with specs and code
For the full SDD workflow (steps, prompts, and a worked example), see Article 2. For the mindset behind combining AaC + SDD + Agentic AI, see Article 4.
From architecture/adr/0001-use-uuid-primary-keys.md:
# Use UUIDs for Primary Keys
* Status: accepted
* Date: 2026-01-12
* Deciders: Architecture Team
## Decision Outcome
Chosen: UUIDs (v4)
### Consequences
✅ Services generate IDs locally with no coordination
✅ Safe merging/importing of data between environments
❌ Larger storage and index size vs integers
❌ Less human-friendly in logs (mitigation: short aliases)From architecture/c4-views/container.md:
Key elements: Web App (React + TypeScript), API Gateway, Microservices (Customer, Order, Product, Payment), RabbitMQ message broker for event-driven communication, PostgreSQL databases per service.
From architecture/models/domain/order.md:
classDiagram
class Order {
uuid id
uuid customerId
OrderStatus status
Money totalAmount
datetime createdAt
addItem(product, quantity)
calculateTotal()
submit()
cancel()
}
From architecture/models/flows/create-order.md:
sequenceDiagram
participant Client
participant OrderService
participant ProductService
participant PaymentService
participant MessageBroker
Client ->> OrderService: POST /orders
OrderService ->> ProductService: Check stock
ProductService -->> OrderService: Stock available
OrderService ->> Database: Create order
OrderService ->> MessageBroker: Publish OrderCreated
MessageBroker -->> PaymentService: Deliver OrderCreated
PaymentService -->> Client: Order confirmation
From architecture/iac/networking.md:
graph TD
Internet["Internet"]
subgraph Public["Public Subnet"]
GW["API Gateway"]
end
subgraph Private["Private Subnet"]
OS["Order Service"]
PY["Payment Service"]
end
subgraph Data["Isolated Data Subnet"]
ODB[("Order DB")]
MQ["RabbitMQ"]
end
Internet --> GW
GW --> OS
GW --> PY
OS --> ODB
OS --> MQ
PY --> MQ
Three network tiers — public (API Gateway), private (services), isolated data (databases + broker) — enforcing the microservices boundaries from ADR-0002 at the network layer. See also IAM and Environments specs.
| Tool | Purpose | Installation |
|---|---|---|
| Structurizr CLI | Generate C4 diagrams from DSL | brew install structurizr-cli or download from GitHub |
| Mermaid CLI | Export Mermaid diagrams to images | npm install -g @mermaid-js/mermaid-cli |
Most IDEs, GitHub, and GitLab render Mermaid diagrams natively—no CLI needed for viewing.
- Fork or clone this repository as a template
- Replace example ADRs with your real architectural decisions
- Update C4 DSL files with your actual system structure
- Customize domain models for your business entities
- Add IaC specs for your networking, IAM, and environment guardrails
- Commit architecture updates in the same PR as implementation changes
Follow the SDD workflow — front-load the thinking, let the AI do the implementation:
- Write a change proposal (
proposal.md,tasks.md) — with AI in plan mode - Review & refine — human judgment, don't skip this
- Implement task by task — AI works from the spec
- Archive & merge — AI archives the spec delta, open the PR
For detailed steps, prompts, and a worked example, see Article 2.
- Plain Text as Code — The manifest behind the mindset: plain text, version-controlled, AI-ready — the philosophy this repository is built on
- OpenSpec — Machine-readable specifications (used in this repo for detailed specs)
- Spec-Driven Development — Wikipedia — Overview of the SDD methodology
- ADR.github.io — Official ADR documentation and templates
- MADR — Markdown ADR format (used in this repo)
- Documenting Architecture Decisions — Original Michael Nygard article
- C4 Model — Official C4 documentation
- Structurizr — C4 tooling and DSL
- Structurizr DSL Reference
- Structurizr Playground — Online DSL editor
- Mermaid.js — Diagram syntax and documentation
- Mermaid Live Editor — Interactive editor and export tool
- Domain-Driven Design — Eric Evans' foundational work
- Fitness Functions — Verifying architecture through automated checks
- What is Infrastructure as Code? — Microsoft — Foundational overview of the IaC concept
- Terraform — Cloud-agnostic IaC tooling
- Bicep — Azure-native IaC language
- Pulumi — IaC using general-purpose programming languages
- David Farley — His peer-reviewed study "Echoes of AI: Investigating the Downstream Effects of AI Assistants on Software Maintainability" (Farley et al., 2025) is referenced in Article 4 and helped ground this project's approach in empirical evidence. His YouTube channel, talks at GOTO Conferences, and the video Modern Software Engineering are highly recommended.
This is an educational example repository demonstrating the Architecture as Code approach.
- Share your experience — Open an issue describing how you adapted this approach
- Suggest improvements — Submit issues for clarifications or enhancements
- Report issues — If you find broken links or unclear documentation
- Fork and adapt — Customize this structure for your organization and share learnings
MIT License — Free to use and adapt for any purpose. See LICENSE for details.
- 🏗️ Start: architecture/README.md — Architecture hub overview
- 🔍 Explore: architecture/ — See the four pillars in action
- 📖 Read: Pick an article from the series for background context
- 💡 Adapt: Fork this repo and customize for your project
Questions or feedback? Open an issue or discussion—we'd love to hear how you're using this approach!
⭐ If this repository helps you, please star it to help others discover architecture-as-code!