This directory contains Architecture Decision Records (ADRs) for the ezDDD.NET project.
- What is an ADR?
- When to Write an ADR
- ADR Format and Template
- Maintenance Workflow and Traceability
- ADR Planning
- ADR Index
- Quality Assurance
An Architecture Decision Record (ADR) is a document that captures an important architectural decision made along with its context and consequences.
Key principles:
- Immutable: Once accepted, ADRs are not modified (except Status)
- Contextual: Records WHY a decision was made, not just WHAT was decided
- Traceable: Linked from planning documents for easy reference
- Versioned: Changes to decisions require new ADRs that supersede old ones
Benefits:
- Provides historical context for future maintainers
- Prevents repeating past discussions
- Makes implicit knowledge explicit
- Helps onboard new team members
- Documents evolution of design philosophy
Create an ADR when making decisions about:
- Framework and tooling choices (e.g., .NET version, test framework)
- Core API design (e.g., module structure, naming conventions)
- Architectural patterns (e.g., event sourcing, CQRS, repository pattern)
- Dependencies (e.g., zero third-party dependency policy, ecosystem dependencies, System.Text.Json usage)
- Breaking changes (e.g., API redesign, major refactoring)
- Performance trade-offs (e.g., reflection vs Expression Trees)
- DDD tactical patterns (e.g., aggregate design, domain event hierarchy)
- Minor bug fixes
- Documentation updates
- Code formatting changes
- Internal refactoring without API impact
Rule of thumb: If an architectural decision is confirmed, write an ADR.
NNNN-short-title.md
NNNN: 4-digit sequence number (e.g., 0001, 0002, 0003)short-title: Kebab-case descriptive title- Examples:
0001-target-framework.md0002-package-naming-and-structure.md0006-event-sourcing-aggregate-design.md
See ADR.template.md for the standard template.
Structure:
# ADR-NNNN: Title
## Status
[Proposed | Accepted | Deprecated | Superseded by ADR-XXXX]
## Context
What is the issue we're facing? What factors are at play?
## Decision
What decision did we make?
## Consequences
### Positive
- What benefits does this decision bring?
### Negative
- What drawbacks or limitations exist?
### Neutral
- What are the trade-offs?
## Alternatives Considered
1. Option A - Why rejected
2. Option B - Why rejected
## Related Decisions
- Related to ADR-XXXX
- Supersedes ADR-YYYY (if applicable)
## References
- Links to relevant documentation
- Discussion threads
- External resourcesADR (docs/adr/*.md)
↓ Summarized in
AGENTS.md
- Detailed, complete decision records
- Once Status is
Accepted, content is immutable - To change a decision, write a new ADR that supersedes the old one
- File naming:
0001-target-framework.md,0002-package-naming.md
- Most concise summary of the rules that affect day-to-day development
- References ADRs for the full rationale (e.g. the R1–R3 event sourcing rules point to ADR-0011)
┌─────────────────────┐
│ Confirm Decision │
└──────────┬──────────┘
↓
┌─────────────────────────────────────┐
│ Step 1: Write ADR │
│ - Use ADR.template.md │
│ - Set Status to "Accepted" │
│ - Save as docs/adr/NNNN-title.md │
└──────────┬──────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Step 2: Update docs/adr/README.md │
│ - Add to ADR Index below │
│ - Update status and date │
└──────────┬──────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Step 3: Update AGENTS.md if the │
│ decision changes day-to-day rules │
└─────────────────────────────────────┘
- Unidirectional References: Guidance documents reference ADRs; ADRs do not depend on guidance documents
- ADR Immutability: Once Accepted, freeze content; changes require new ADR
- Explicit ADR Numbers: Always include
[ADR-NNNN]links in all locations - Periodic Sync Check: When confirming decisions, update the ADR, this index, and AGENTS.md together
This section will be updated as ADRs are created.
| ADR | Title | Date | Status |
|---|---|---|---|
| ADR-0001 | Target Framework - .NET 8 | 2025-10-31 | Accepted |
| ADR-0002 | Package Naming and Structure | 2025-10-28 | Accepted |
| ADR-0003 | Module Architecture and Dependency Chain | 2025-10-31 | Accepted |
| ADR-0004 | Zero Third-Party Dependency Principle | 2025-10-31 | Accepted |
| ADR-0005 | Complete Reimplementation Approach | 2025-10-31 | Accepted |
| ADR-0006 | uContract.NET Integration for Design by Contract | 2025-10-31 | Accepted |
| ADR-0007 | IEntity and IValueObject Design | 2025-11-01 | Accepted |
| ADR-0008 | IDomainEvent Hierarchy Design | 2025-11-01 | Accepted |
| ADR-0009 | AggregateRoot Base Class Design | 2025-11-01 | Accepted |
| ADR-0010 | EsAggregateRoot Event Sourcing Implementation (R1, R2, R3 Rules) | 2025-11-01 | Accepted |
| ADR-0011 | Event Replay and Invariant Checking | 2025-11-01 | Accepted |
| ADR-0012 | Resource Management Pattern for External Event Bus Producers | 2025-11-10 | Accepted |
| ADR-0013 | Transaction Boundaries in Repository Pattern | 2025-11-10 | Accepted |
| ADR-0014 | DomainEventData Equality Semantics | 2025-11-10 | Accepted |
| ADR-0015 | Cross-Platform DTO Structure (InternalDomainEventDto) | 2025-11-10 | Accepted |
| ADR-0016 | Async/Await Throughout (All I/O Operations) | 2025-11-10 | Accepted |
| ADR-0017 | CqrsOutput Implementation Strategy | 2025-11-17 | Accepted |
| ADR-0018 | IArchive Async Method Design | 2025-11-17 | Accepted |
| ADR-0019 | IInquiry and IProjection Independence from IUseCase | 2025-11-17 | Accepted |
| ADR-0021 | Generic Variance Annotations for CQRS Interfaces | 2025-11-18 | Accepted |
| ADR-0022 | Read Model Design Patterns | 2025-11-18 | Accepted |
| ADR-0023 | Archive Idempotency Requirements | 2025-11-18 | Accepted |
| ADR-0024 | IReconciler Interface for System State Reconciliation | 2026-01-07 | Accepted |
| ADR-0025 | MessageProducer Refactoring - Java 4.1.0 Alignment | 2026-01-07 | Accepted (Amended by ADR-0029) |
| ADR-0026 | Service Layer Pattern for Complex Business Logic | 2026-01-08 | Accepted |
| ADR-0027 | Thread Safety and Null Safety Review (Java 4.1.0 Sync - Stage S5) | 2026-01-08 | Accepted |
| ADR-0028 | Reactor Type Hierarchy and Projector/Notifier Genericization | 2026-07-04 | Accepted |
| ADR-0029 | MessageProducer Removal from Core & Gateway Package Deferral | 2026-07-04 | Accepted |
(None yet)
(None yet)
| ADR | Title | Date | Status |
|---|---|---|---|
| ADR-0020 | IProjector Lifecycle Management Integration | 2025-11-18 | Superseded by ADR-0028 |
Before writing or updating any ADR, check for these common issues:
- ✅ Generic constraint correctness (especially for aggregate types)
- ✅ Cross-reference accuracy (verify ADR numbers exist)
- ✅ Bidirectional references (if A → B, then B should mention A)
- ✅ Code example consistency across all ADRs
- ✅ Up-to-date ADR index in this README
Key Rules for ezDDD.NET:
EsAggregateRoot<TId, TEvent>→ MUST havewhere TEvent : InternalDomainEventIRepository<TAggregate, TId>→ MUST havewhere TAggregate : AggregateRoot<TId, InternalDomainEvent>- Always verify ADR numbers before referencing
- Update bidirectional references when adding new "Related to" entries
Run these commands in docs/adr/ before committing:
# Check for broken ADR references
grep -r "ADR-[0-9]\{4\}" *.md | grep -o "ADR-[0-9]\{4\}" | sort -u
# Verify all referenced ADRs exist
for adr in $(grep -rho "ADR-[0-9]\{4\}" *.md | sort -u); do
file="${adr#ADR-}-*.md"
if ! ls $file 2>/dev/null; then
echo "Missing: $adr"
fi
done- Copy
ADR.template.mdtoNNNN-your-title.md(use next sequence number) - Fill in all sections
- Set initial Status to "Proposed" or "Accepted"
- Update this README's ADR Index
- Follow the maintenance workflow
- Proposed → Accepted: Decision is finalized
- Accepted → Deprecated: No longer recommended but not replaced
- Accepted → Superseded by ADR-XXXX: Replaced by a new decision
- Write ADRs during decision-making, not after implementation
- Keep ADRs concise but complete (1-3 pages max)
- Focus on WHY, not just WHAT
- Include alternatives considered to avoid future repetition
- Link to related ADRs to build decision graph
- Reference Java ezddd when comparing implementations
- ADR Template - Standard ADR format
- AGENTS.md - Development guidance
- Java ezddd - Original implementation
- uContract.NET ADRs - Reference implementation
This README follows the ADR maintenance workflow defined above. Last Updated: 2026-07-04