DDD Integration — Essential Core in AI-Driven Development
Key Message: This guide selects DDD as a methodology flavor to apply within AIDLC and recommends it as a default element. AI models business logic according to DDD principles, and teams validate and adjust. DDD is not an inherent mandatory core of AIDLC itself but an option this guide recommends.
1. Why This Guide Recommends DDD
In traditional Scrum, DDD (Domain-Driven Design) was a team choice. If architects preferred DDD, they adopted it; otherwise, they proceeded with transaction scripts or layered architecture. The choice of design technique depended on team capability and preference.
This guide selects and recommends DDD/BDD/TDD as default flavors to apply within AIDLC. This does not mean the AIDLC methodology itself mandates them; it is the combination of design techniques this guide chooses in order to gain consistency in AI-driven code generation.
Traditional SDLC This guide's AIDLC application
━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━
Design techniques are team choice DDD/BDD/TDD recommended as default flavors
Architects manually model AI models automatically, team validates
Design docs gradually drift from code Spec → Code consistency auto-maintained
Domain knowledge exists only in heads Formalized as ontology, understood by AI
1.1 Why DDD is Recommended
AI performs best with structured patterns. DDD provides clear vocabulary and rules for organizing business logic into Aggregate, Entity, Value Object, Domain Event. This acts as consistent guardrails when AI transforms requirements into code.
Unstructured requirements + AI = Arbitrary implementation (different style each time)
DDD patterns + AI = Predictable implementation (Aggregate-first, Event-driven)
1.2 Scrum vs AIDLC: DDD's Positional Change
| Aspect | Scrum + DDD (Optional) | AIDLC + DDD (Essential) |
|---|---|---|
| Adoption | Architect discretion | Built into methodology |
| Modeling Lead | Architect + Developers | AI draft → Team validation |
| Maintenance | Manual doc synchronization | Automatic Spec file reflection |
| Learning Curve | High (Red/Blue Book) | Low (AI applies patterns) |
| Application Scope | Core domain only | Consistent across all Units |
2. Inception Phase: From Requirements to Design
DDD integration begins in the Inception phase. The core ritual of this phase is Mob Elaboration, where AI automatically models requirements into DDD patterns and the team validates them.
2.1 Mob Elaboration Ritual
Mob Elaboration is a requirements refinement session where Product Owner, developers, and QA gather in one room to collaborate with AI.
┌──────────────────────────────────────────────────┐
│ Mob Elaboration Ritual │
├──────────────────────────────────────────────────┤
│ │
│ [AI] Proposes Intent decomposition into │
│ User Stories + Units │
│ ↓ │
│ [PO + Dev + QA] Review · Adjust over/under- │
│ design │
│ ↓ │
│ [AI] Reflects modifications → Generates │
│ additional NFRs · Risks │
│ ↓ │
│ [Team] Final validation → Confirm Bolt plan │
│ │
├──────────────────────────────────────────────────┤
│ Deliverables: │
│ PRFAQ · User Stories · NFR definitions │
│ Risk Register · Metrics · Bolt plan │
└──────────────────────────────────────────────────┘
Time Compression Effect: Sequential requirements analysis that took weeks to months in traditional methodologies is compressed to hours as AI generates drafts and teams review simultaneously.
2.2 Kiro Spec-Driven Inception
Kiro systematizes Mob Elaboration deliverables as Spec files. It structures the entire process from natural language requirements to code. The requirements.md → design.md → tasks.md flow below is the output structure this guide pins to the AIDLC Vibe workflow; it does not necessarily match the file names and stages used by Kiro's own built-in Spec feature. Verify each tool's actual Spec behavior against that tool's current documentation.
2.2.1 Payment Service Example
requirements.md:
# Payment Service Deployment Requirements
## Functional Requirements
- REST API endpoint: /api/v1/payments
- Integration with DynamoDB table
- Asynchronous event processing via SQS
## Non-Functional Requirements
- P99 latency: < 200ms
- Availability: 99.95%
- Auto-scaling: 3-20 Pods (minimum 3, HPA max 20)
- EKS 1.35+ compatibility
The design above assumes an EKS 1.35+ cluster with the ACK controllers (DynamoDB, SQS), Karpenter, and HPA already installed.
design.md:
# Payment Service Architecture
## Domain Model (DDD)
- Aggregate: Payment (transactionId, amount, status)
- Entity: PaymentMethod, Customer
- Value Object: Money, Currency
- Domain Event: PaymentCreated, PaymentCompleted, PaymentFailed
## Infrastructure Configuration
- EKS Deployment (replicas: 3, HPA max 20)
- ACK DynamoDB Table (on-demand)
- ACK SQS Queue (FIFO)
- HPA (CPU 70%, Memory 80%)
- Karpenter NodePool (graviton, spot)
## Observability
- ADOT sidecar (traces → X-Ray)
- Application Signals (automatic SLI/SLO)
- CloudWatch Logs (/eks/payment-service)
## Security
- Pod Identity (IRSA replacement)
- NetworkPolicy (namespace isolation)
- Secrets Manager CSI Driver
tasks.md:
# Implementation Tasks
## Bolt 1: Domain Model
- [ ] Implement Payment Aggregate
- [ ] Define Value Objects (Money, Currency)
- [ ] Define Domain Events
- [ ] Define Repository interface
## Bolt 2: Infrastructure
- [ ] Write ACK DynamoDB Table CRD
- [ ] Write ACK SQS Queue CRD
- [ ] Configure Karpenter NodePool
## Bolt 3: Application
- [ ] Implement Go REST API
- [ ] Implement DynamoDB Repository
- [ ] Implement SQS Event Publisher
- [ ] Dockerfile + multi-stage build
## Bolt 4: Deployment & Observability
- [ ] Write Helm chart
- [ ] Configure ADOT sidecar
- [ ] Application Signals annotation
Directive Approach: "Create DynamoDB" → "Need SQS too" → "Now deploy" → Manual instructions each time, risk of context loss
Spec-Driven: Kiro analyzes requirements.md → generates design.md → decomposes tasks.md → auto-generates code → connects validation with consistent Context Memory
2.3 MCP-Based Real-Time Context Collection
Kiro is MCP native, collecting real-time infrastructure state through AWS Hosted MCP servers during the Inception phase.
The calls and responses below are illustrative of the interaction; the actual tool names, schemas, and response formats of each MCP server follow the documentation of the server version you use.
[Kiro + MCP Interaction]
Kiro: "Check EKS cluster status"
→ EKS MCP Server: get_cluster_status()
→ Response: { version: "1.35", nodes: 5, status: "ACTIVE" }
Kiro: "Analyze costs"
→ Cost Analysis MCP Server: analyze_cost(service="EKS")
→ Response: { monthly: "$450", recommendations: [...] }
Kiro: "Analyze current workloads"
→ EKS MCP Server: list_deployments(namespace="payment")
→ Response: { deployments: [...], resource_usage: {...} }
This enables design reflecting current cluster state and costs when generating design.md.
3. Construction Phase: DDD Pattern Implementation
In the Construction phase, AI transforms domain models defined in Inception into actual code. During this process, DDD patterns are mapped to AWS services and Kubernetes resources.
3.1 From Domain Design to Logical Design
3.1.1 Payment Service Implementation Steps
Step 1: Domain Design — AI models business logic
// Aggregate
// The DynamoDB partition key maps to TransactionID (the "transactionId" attribute), matching the Table CRD keySchema HASH key.
type Payment struct {
TransactionID string `dynamodbav:"transactionId"` // partition key (HASH)
Amount Money `dynamodbav:"amount"`
Status PaymentStatus `dynamodbav:"status"`
Customer Customer `dynamodbav:"customer"`
Method PaymentMethod `dynamodbav:"method"`
Events []DomainEvent `dynamodbav:"-"` // not persisted (separated into the outbox)
}
// Value Object
type Money struct {
Amount decimal.Decimal
Currency Currency
}
// Domain Event
type PaymentCreated struct {
TransactionID string
Timestamp time.Time
}
Step 2: Logical Design — Apply NFRs + Select architecture patterns
- CQRS Pattern: Separate payment creation (Command) / lookup (Query)
- Command: POST /api/v1/payments → DynamoDB write + SQS publish
- Query: GET /api/v1/payments/{id} → DynamoDB Streams → ElastiCache read
- Circuit Breaker: Envoy sidecar + Istio for external payment gateway calls
- ADR (Architecture Decision Record): Record "DynamoDB on-demand vs provisioned" decision
Step 3: Code Generation — AWS service mapping
| DDD Element | AWS/Kubernetes Mapping |
|---|---|
| Aggregate (Payment) | EKS Deployment + DynamoDB Table |
| Domain Event | SQS FIFO Queue |
| Repository | DynamoDB SDK with ACK CRDs |
| Circuit Breaker | Envoy sidecar (Istio) |
| Event Publisher | SQS SDK with retry logic |
3.2 Detailed AWS Service Mapping
3.2.1 DynamoDB Table (Aggregate Persistence)
AI analyzes Aggregate definitions in design.md to auto-generate ACK CRDs.
apiVersion: dynamodb.services.k8s.aws/v1alpha1
kind: Table
metadata:
name: payment-table
spec:
tableName: payment-service
attributeDefinitions:
- attributeName: transactionId
attributeType: S
keySchema:
- attributeName: transactionId
keyType: HASH
billingMode: PAY_PER_REQUEST # Decided in ADR
tags:
- key: DomainAggregate
value: Payment
3.2.2 SQS Queue (Domain Event Publishing)
apiVersion: sqs.services.k8s.aws/v1alpha1
kind: Queue
metadata:
name: payment-events
spec:
queueName: payment-service-events.fifo
fifoQueue: "true"
contentBasedDeduplication: "true"
tags:
DomainEvent: PaymentCreated,PaymentCompleted,PaymentFailed
3.2.3 Repository Implementation
AI implements DDD Repository pattern with DynamoDB SDK.
type PaymentRepository interface {
Save(ctx context.Context, payment *Payment) error
FindByID(ctx context.Context, id string) (*Payment, error)
}
type DynamoDBPaymentRepository struct {
client *dynamodb.Client
}
func (r *DynamoDBPaymentRepository) Save(ctx context.Context, p *Payment) error {
item, err := attributevalue.MarshalMap(p)
if err != nil {
return err
}
// Write the aggregate and its domain events in one transaction (outbox pattern)
outboxItems := marshalOutbox(p.Events)
_, err = r.client.TransactWriteItems(ctx, &dynamodb.TransactWriteItemsInput{
TransactItems: append([]types.TransactWriteItem{
{Put: &types.Put{TableName: aws.String("payment-service"), Item: item}},
}, outboxItems...),
})
if err != nil {
// On persistence failure, return without publishing (state and events commit or fail together)
return err
}
// Publishing is done asynchronously from the outbox (a separate relay guarantees retries)
return nil
}
3.3 NFR Application: CQRS, Circuit Breaker, ADR
3.3.1 CQRS Pattern
AI analyzes NFR (P99 < 200ms) to propose Command/Query separation.
Command Side (Write):
POST /api/v1/payments
→ Aggregate.CreatePayment()
→ DynamoDB.PutItem()
→ SQS.SendMessage(PaymentCreated)
Query Side (Read):
GET /api/v1/payments/\{id\}
→ ElastiCache.Get(id) # DynamoDB Streams → Cache
→ Fallback: DynamoDB.GetItem()
3.3.2 Circuit Breaker (External Gateway)
This is a passive outlier-detection policy for an external payment gateway. consecutive5xxErrors: 5 sets a consecutive observed HTTP 5xx threshold; it does not establish successful failure isolation.
Applicability: This example uses the Istio 1.27.0 v1beta1 fields. Verify that the installed release serves the required CRD, then register the real gateway host in Istio's service registry, for example with a ServiceEntry. Configure the request path through an Envoy sidecar, ports/protocols and TLS handling.
A proxy passing HTTPS through cannot read the encrypted HTTP status. This policy requires Envoy to observe the error responses. The snippet supplies only the outlier-detection portion; prepare host registration and TLS configuration separately.
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: payment-gateway-circuit-breaker
spec:
host: external-payment-gateway.com
trafficPolicy:
outlierDetection:
consecutive5xxErrors: 5
interval: 30s
baseEjectionTime: 60s
3.3.3 Automatic ADR Generation
AI records architecture decisions in ADR format when writing design.md.
# ADR-001: Choosing DynamoDB On-Demand
## Context
Payment Service has irregular and unpredictable traffic patterns.
## Decision
Choose On-Demand instead of Provisioned Capacity.
## Consequences
- Cost: can be more expensive than Provisioned Capacity when traffic is steady and predictable (the difference depends on traffic pattern and utilization, so calculate it from pricing and record the result)
- Advantage: Automatic spike traffic handling, no scaling operations
- Disadvantage: Cost optimization limitations
4. Mob Construction Ritual
The core ritual of Construction is Mob Construction. Teams gather in one room to develop their respective Units, exchanging Integration Specifications generated during the Domain Design stage.
[Mob Construction Flow]
Team A: Payment Unit Team B: Notification Unit
│ │
├─ Domain Design complete ├─ Domain Design complete
│ │
└────── Exchange Integration Spec ──────┘
(Domain Event contract)
│ │
├─ Logical Design ├─ Logical Design
├─ Code generation ├─ Code generation
├─ Testing ├─ Testing
└─ Bolt delivery └─ Bolt delivery
4.1 Domain Event-Based Integration
Each Unit is loosely coupled enabling parallel development, integrated through Domain Events.
Integration Specification:
# payment-unit-events.yaml
events:
- name: PaymentCompleted
schema:
transactionId: string
amount: decimal
currency: string
timestamp: ISO8601
# A single SQS queue does not fan out to multiple consumers, so publish to an
# SNS topic (or EventBridge) and subscribe a per-consumer SQS queue.
publishTo: sns:payment-events-topic
subscribers:
- notification-unit # subscribes its own queue payment-events-notification
- analytics-unit # subscribes its own queue payment-events-analytics
AI auto-generates integration tests based on this spec.
func TestPaymentNotificationIntegration(t *testing.T) {
// Payment Unit publishes PaymentCompleted event
payment := CreatePayment(amount)
payment.Complete()
// Receive from the notification-specific queue and deserialize into a typed event
msg := sqsClient.ReceiveMessage("payment-events-notification")
var event PaymentCompletedEvent
require.NoError(t, json.Unmarshal([]byte(msg.Body), &event))
assert.Equal(t, "PaymentCompleted", event.Type)
// Verify Notification Unit sent email
notification := notificationClient.GetLastNotification()
assert.Contains(t, notification.Body, payment.TransactionID)
}
4.2 AI Extension of Pair Programming
Mob Construction is traditional Pair Programming extended with AI.
| Aspect | Pair Programming | Mob Construction (AI) |
|---|---|---|
| Participants | 2 (Driver + Navigator) | N people + AI Agent |
| Roles | 1 codes, 1 reviews | N people validate, AI codes |
| Speed | Human speed | Can be faster since AI generates code (multiplier unvalidated) |
| Parallelism | Sequential work | Multiple Units parallel |
| Knowledge Transfer | Only 2 learn | Entire team learns simultaneously |
The speed comparison above indicates a relative tendency; the specific multiplier is an unvalidated assumption, not a measured value. The actual improvement depends on the nature of the work, team composition, and validation cost.
5. Brownfield (Existing System) Approach
This section describes a methodology approach you may choose when adding features to or refactoring existing systems. The reverse-engineering flow below is not an additional tagged step inserted into the Construction phase; it is a discussion of how to lift existing code into DDD models. Adopt it based on your team's situation.
This is an option that prioritizes optimizing existing systems over building new. AI reverse-engineers legacy code into DDD models to support gradual refactoring.
5.1 Reverse Engineering Process
Step 1: AI reverse-engineers existing code into semantic model (promote code → model)
-
Static Model: Components, responsibilities, relationships
[PaymentController] → [PaymentService] → [PaymentDAO]
- PaymentService responsibilities: Business logic + Transaction management
- PaymentDAO responsibilities: Data access -
Dynamic Model: Component interactions in major use cases
Payment Creation Flow:
Controller.createPayment()
→ Service.processPayment()
→ DAO.insertPayment()
→ DAO.insertPaymentEvent()
Step 2: Developers validate and modify reverse-engineered model
Verify that AI-extracted model accurately reflects actual business intent.
Step 3: Proceed with same Construction flow as Green-field
Redesign reverse-engineered model into DDD Aggregate/Entity/Value Object, AI generates refactoring code.
5.2 Gradual Refactoring Strategy
Don't refactor entire system at once, perform gradual transition in Bolt units.
Bolt 1: Extract Payment Aggregate
- Before: PaymentService (God Object 900 lines)
- After: Payment Aggregate + PaymentRepository
Bolt 2: Introduce Domain Events
- Before: Direct Notification call on payment completion
- After: Publish PaymentCompleted event → SQS → Notification subscription
Bolt 3: CQRS Separation
- Before: Read/write mixed in single Service
- After: Separate PaymentCommandService / PaymentQueryService
6. Extension to Ontology: From DDD to Formal Ontology
"Prompt engineering is ontology engineering" — a summary of this document's position, not a quotation from a specific source
DDD's Ubiquitous Language is an informal agreement for team communication. In the AI era, this must be elevated to formal ontology (typed world model) so AI can mechanically understand and comply.
6.1 DDD vs Ontology
| Aspect | DDD (Ubiquitous Language) | Formal Ontology |
|---|---|---|
| Definition | Natural language agreement | Machine-interpretable schema |
| Primary Target | Humans (team communication) | AI + Humans |
| Validation | Manual during code review | Validation at prompt time when a validator and domain boundary are defined |
| Evolution | Documentation lag | Schema version control |
| Example | "Payments have created, completed, failed states" | Payment.status: enum(CREATED, COMPLETED, FAILED) |
In the table above, "validation at prompt time" holds only when a validator and domain boundary are defined for the schema. Without such a validator, the schema is only context passed to the AI, not an enforced constraint.
6.2 Ontology Engineering Workflow
1. Define DDD model (requirements.md, design.md)
↓
2. AI generates ontology schema (JSON Schema/OWL)
↓
3. Ontology validation (team review)
↓
4. AI generates code based on ontology
↓
5. Runtime validation (ontology ↔ actual behavior match)
This process is covered in detail in the Ontology Engineering document.
7. Quality Gates: DDD Pattern Validation
Automatically validate that AI-generated code in the Construction phase complies with DDD principles.
7.1 Harness Engineering Integration
Quality Gates defined in Harness Engineering validate DDD patterns.
# quality-gates.yaml
gates:
- name: DDD Pattern Compliance
rules:
- check: "Does Aggregate maintain single transaction boundary?"
tool: static-analysis
- check: "Are Domain Events named in past tense?"
tool: naming-convention
- check: "Do Value Objects ensure immutability?"
tool: immutability-checker
- check: "Does Repository only persist Aggregates?"
tool: dependency-analysis
7.2 Automatic Validation Example
// ❌ Anti-pattern: Aggregate directly references another Aggregate
type Order struct {
OrderID string
Customer Customer // ❌ Direct Customer Aggregate reference
}
// ✅ Best practice: Reference only by ID
type Order struct {
OrderID string
CustomerID string // ✅ Store only ID, retrieve via Repository when needed
}
AI automatically detects these patterns and generates modification suggestions.
8. AI Coding Agents: DDD Implementation Automation
AI coding agents used in AIDLC Construction phase automatically apply DDD patterns.
8.1 Kiro's DDD Automation
Kiro is an AI coding agent developed by AWS Labs that performs Spec-Driven DDD implementation.
Kiro Workflow:
1. Analyze requirements.md → Extract domain concepts
2. Generate design.md → Identify Aggregate/Entity/Value Object
3. Decompose tasks.md → Plan Bolt-unit implementation
4. Auto-generate code → Apply DDD patterns
5. Auto-generate tests → Validate domain logic
8.2 Amazon Q Developer's Real-Time Validation
Amazon Q Developer announced on January 31, 2025 validates DDD implementation through automatic build and test execution. This capability works when the project has build and test commands configured (for example, specifying the commands to run via a Devfile) and runnable tests exist.
Traditional Approach:
AI generates code → Developer manually builds → Discovers test failures → Repeat fixes
Q Developer:
AI generates code → Auto-build → Auto-test → Iterate code fixes on failure, then request review
This is a core mechanism that activates AIDLC's Loss Function early in the Construction phase, preventing downstream error propagation.
Refer to the AI Coding Agents document for detailed comparison.
9. DDD Application in MSA Environments
In complex Microservices Architecture (MSA) environments, DDD is core to setting service boundaries and integration strategies.
9.1 Bounded Context and Service Boundaries
DDD's Bounded Context naturally maps to MSA's service boundaries.
Payment Bounded Context → Payment Service
Notification Bounded Context → Notification Service
Analytics Bounded Context → Analytics Service
AI analyzes requirements.md to auto-identify Bounded Contexts. A Bounded Context is only a boundary of the domain model; how it is realized as a deployment unit is a separate decision. Mapping each service to an independent EKS Deployment is one possible topology, but a monolithic deployment or a different runtime are also valid choices.
9.2 Context Mapping Patterns
Apply DDD Context Mapping patterns when multiple services interact.
| Pattern | Description | Implementation |
|---|---|---|
| Customer-Supplier | One team provides API to another | REST API + API Gateway |
| Conformist | Downstream team adopts upstream model as-is | Common Proto/Schema |
| Anticorruption Layer | Isolation from legacy systems | Adapter pattern |
| Shared Kernel | Share common domain model | Shared Library (minimize) |
| Published Language | Standard event format | CloudEvents + SQS |
Refer to the MSA Complexity document for DDD application strategies in complex MSA environments.
10. Key Summary
10.1 Why is DDD an Essential Core of AIDLC
- AI performs best with structured patterns — DDD provides clear vocabulary and rules
- Automatic Spec → Code transformation — requirements.md → design.md → tasks.md → code
- Team validation is Loss Function — AI draft → Team adjustment → AI improvement → Repeat
- Evolution to ontology — Informal language → Formal schema → AI mechanical understanding
10.2 Core Rituals
- Mob Elaboration (Inception): Requirements → DDD model, weeks → hours compression
- Mob Construction: Parallel Unit development, Domain Event-based integration
10.3 Automation Scope
| Phase | AI Automation | Human Role |
|---|---|---|
| Domain Design | Aggregate/Entity/VO draft | Validate business accuracy |
| Logical Design | Apply CQRS/Circuit Breaker | Decide NFR priorities |
| Code Generation | Implement DDD patterns | Code review |
| Test Generation | Domain logic tests | Validate scenarios |
| ADR Writing | Record architecture decisions | Approve decisions |
11. Next Steps
- Ontology Engineering — Extension from DDD to formal ontology
- Harness Engineering — Validate DDD patterns in Quality Gates
- AI Coding Agents — Kiro, Q Developer details
- MSA Complexity — DDD application in complex MSA
📚 References
- AWS, "AI-Driven Development Life Cycle: Reimagining Software Engineering" (AWS DevOps Blog): aws.amazon.com/blogs/devops/ai-driven-development-life-cycle
- AWS Labs, AI-DLC Workflows: github.com/awslabs/aidlc-workflows
- Eric Evans, "Domain-Driven Design" (2003)
- Vaughn Vernon, "Implementing Domain-Driven Design" (2013)
- Chris Richardson, "Microservices Patterns" (2018)