7.8 KiB
Decisions
This document contains Architecture Decision Records (ADRs).
Use ADRs for decisions that materially affect architecture, operations, security, team workflow, data ownership, public contracts, or long-term maintainability.
For architecture context, see ARCHITECTURE.md. For project constraints, see PROJECT.md.
Status Values
- Proposed: under discussion.
- Accepted: current decision.
- Superseded: replaced by a newer decision.
- Deprecated: no longer recommended, but still present.
- Rejected: considered and intentionally not chosen.
ADR Index
| ID | Title | Status | Date |
|---|---|---|---|
| ADR-000 | ADR template | Accepted | {{DATE}} |
| ADR-001 | Example: Start with a modular monolith | Example | 2026-06-28 |
| ADR-002 | Example: Keep project documentation in the repository | Example | 2026-06-28 |
| ADR-003 | Example: Require explicit validation evidence before merge | Example | 2026-06-28 |
| ADR-004 | Example: Use repository pattern for persistence boundaries | Example | 2026-06-28 |
ADR-000: ADR Template
Title
{{DECISION_TITLE}}
Status
{{STATUS}}
Date
{{DATE}}
Context
{{CONTEXT}}
Describe the environment, constraints, project stage, team needs, and forces that make the decision necessary.
Problem
{{PROBLEM}}
State the specific problem being solved. Avoid combining unrelated decisions.
Alternatives
| Alternative | Summary |
|---|---|
{{ALTERNATIVE_1}} |
{{ALTERNATIVE_1_SUMMARY}} |
{{ALTERNATIVE_2}} |
{{ALTERNATIVE_2_SUMMARY}} |
{{ALTERNATIVE_3}} |
{{ALTERNATIVE_3_SUMMARY}} |
Pros
{{PRO}}
Cons
{{CON}}
Decision
{{DECISION}}
Write the chosen option and why it best fits the current constraints.
Consequences
{{CONSEQUENCE}}
Document expected benefits, costs, operational impacts, migration needs, and future review triggers.
ADR-001: Example: Start With A Modular Monolith
Title
Start with a modular monolith before introducing microservices.
Status
Example
Date
2026-06-28
Context
The fictional project Atlas Desk is a new workflow application with one small
team, one primary database, and requirements that are still evolving.
Problem
The team needs clear module boundaries without accepting the operational cost of distributed services too early.
Alternatives
| Alternative | Summary |
|---|---|
| Layered monolith | Simple to build, but feature boundaries may become unclear. |
| Modular monolith | Strong internal boundaries with one deployable unit. |
| Microservices | Independent deployments, but higher operational and data consistency cost. |
Pros
- Preserves deployment simplicity.
- Supports clear module ownership.
- Avoids premature distributed transactions and network failure modes.
- Allows extraction of services later when boundaries are proven.
Cons
- Requires discipline to maintain module boundaries.
- Independent scaling by module is limited.
- Poor internal boundaries can still create a tightly coupled system.
Decision
Use a modular monolith as the initial architecture.
Consequences
- Module boundaries must be documented in ARCHITECTURE.md.
- Cross-module access must go through public interfaces.
- Service extraction can be reconsidered when team scale, traffic, or ownership pressure justifies it.
ADR-002: Example: Keep Project Documentation In The Repository
Title
Keep durable engineering documentation in the source repository.
Status
Example
Date
2026-06-28
Context
The project will use issue trackers and chat for coordination, but architecture, setup, and operating knowledge must remain discoverable by humans and AI agents.
Problem
External documentation often drifts from code and is harder for development tools to discover during implementation.
Alternatives
| Alternative | Summary |
|---|---|
| Repository documentation | Versioned with code and easy for agents to read. |
| Wiki | Easier non-developer editing, but often drifts from code changes. |
| Chat-only knowledge | Fast, but not durable or discoverable. |
Pros
- Documentation changes can be reviewed with code.
- Agents and developers can discover project context locally.
- Historical context remains connected to commits.
Cons
- Non-developers may find editing less convenient.
- Documentation quality still requires review discipline.
- Large diagrams or rich media may need external tooling.
Decision
Keep durable engineering documentation in the repository under docs/.
Consequences
- Pull requests that change architecture or operations should update docs.
- Temporary planning can live elsewhere, but accepted decisions belong here.
- Links must be reviewed as part of documentation changes.
ADR-003: Example: Require Explicit Validation Evidence Before Merge
Title
Require explicit validation evidence before merging changes.
Status
Example
Date
2026-06-28
Context
The project may use AI-assisted development and multiple contributors. Reviewers need a reliable way to understand how changes were checked.
Problem
Pull requests without validation evidence increase review time and regression risk.
Alternatives
| Alternative | Summary |
|---|---|
| No required evidence | Fastest locally, but makes review less reliable. |
| Validation summary in PR | Lightweight and visible to reviewers. |
| Full test report artifact only | Detailed, but harder to scan for small changes. |
Pros
- Reviewers can evaluate risk quickly.
- Missing tests or blocked checks are visible.
- AI-generated changes become easier to trust or challenge.
Cons
- Contributors must spend time recording checks.
- Some exploratory changes may need a lighter process before formal review.
Decision
Every pull request must include a short validation section listing commands, manual checks, or reasons validation could not be run.
Consequences
- PR templates should include validation.
- Reviewers can block merges when risk is high and evidence is missing.
- Failed or skipped validation must be explained.
ADR-004: Example: Use Repository Pattern For Persistence Boundaries
Title
Use repository pattern for persistence boundaries.
Status
Example
Date
2026-06-28
Context
The project needs domain and application logic to remain independent from the database engine, ORM, and storage implementation details.
Problem
Without an explicit persistence boundary, database concerns can leak into business logic and make testing, refactoring, and future storage changes harder.
Alternatives
| Alternative | Summary |
|---|---|
| Direct ORM access everywhere | Fast initially, but couples business logic to persistence details. |
| Generic repository | Reduces ORM exposure, but often becomes a thin CRUD wrapper. |
| Domain-specific repository pattern | Keeps persistence behind intention-revealing interfaces. |
Pros
- Keeps application and domain logic focused on use cases and rules.
- Makes persistence behavior easier to test and replace.
- Creates a clear place for query intent and transaction expectations.
- Reduces accidental coupling to ORM-specific APIs.
Cons
- Adds interfaces and implementation classes.
- Poorly designed repositories can hide important query or transaction costs.
- Generic repositories can obscure domain behavior if used mechanically.
Decision
Use domain-specific repositories as the default persistence boundary.
Consequences
- Repository interfaces should live at the application or domain boundary.
- Repository implementations should live in infrastructure or persistence modules.
- Generic CRUD repositories should be avoided unless the project records a clear reason.
- Transaction boundaries must be documented where writes span multiple repositories.