Context drives decisions. No pattern is universally good or bad. The best architecture is not the most elegant โ it's the one that best serves its purpose while remaining maintainable and evolvable.
Every architectural decision trades off:
| Vertex | Maximized By | Cost |
|---|
| Simplicity | Monolith, sync communication, single DB | Scalability limits |
| Flexibility | Microservices, event-driven, plugins | Complexity overhead |
| Performance | Caching, denormalization, optimized code | Maintainability |
Balance strategies: start simple; add complexity as needed; measure before optimizing; use abstractions to defer decisions; evolve incrementally.
SHOULD read CONTEXT.md at repo root before proceeding โ use its vocabulary verbatim; never substitute synonyms.
SHOULD scan docs/adr/ for decisions in the area under analysis โ respect accepted ADRs; do not re-litigate closed decisions.
If neither exists, proceed without them. Do not create these files unprompted.
MUST consider team and scale context before recommending patterns.
Team context:
| Context | Prefer | Avoid |
|---|
| Small team | Monolith, vertical slices, shared DB | Microservices, complex abstractions |
| Multiple teams | Service boundaries, API contracts | Shared state, tight coupling |
Scale context:
| Context | Prefer | Reasoning |
|---|
| Startup / early | Monolith first, vertical scaling | Optimize for development speed |
| Enterprise | Service mesh, horizontal scaling | Optimize for operational scale |
Quality attributes to surface:
- Performance: response time (p50/p95/p99), throughput, resource utilization
- Scalability: horizontal, vertical, elastic
- Reliability: uptime, MTBF, MTTR; patterns = circuit breakers, retries, redundancy
- Maintainability: readability, modularity, testability; patterns = Clean Architecture, DDD, SOLID
Use weighted matrix for comparing alternatives. Weight factors based on context priorities.
| Option | Consistency | Flexibility | Scalability | Complexity | Cost | Total |
|---|
| Option A | 5 | 2 | 3 | 2 | 3 | 15 |
| Option B | 3 | 5 | 4 | 3 | 3 | 18 |
| Option C | 2 | 3 | 5 | 1 | 2 | 13 |
MUST list criteria and weights before scoring. MUST justify weights against stated context.
Use ADR for any decision that would be expensive to reverse.
Write to docs/adr/NNNN-<slug>.md โ NNNN = next available number zero-padded to 4 digits; slug = lowercase-hyphenated title. Create docs/adr/ if absent.
For the full ADR template (frontmatter + sections) and supersede mechanics, read references/adr-template.md.
Branch by Abstraction โ create abstraction over current implementation โ implement new solution behind abstraction โ switch โ remove old.
Strangler Fig โ identify boundary โ implement new solution for new features โ gradually migrate old features โ retire old system.
Parallel Run โ implement new solution โ run both old and new โ compare results โ switch when confident.
| Type | Examples | Payment Strategy |
|---|
| Design | Missing abstractions, tight coupling | Refactoring sprints |
| Code | Duplication, complexity, poor naming | Continuous cleanup |
| Test | Missing tests, flaky tests | Test improvement |
| Documentation | Missing docs, outdated diagrams | Documentation sprints |
Metrics: debt ratio = debt work / total work (target < 20%); interest rate = extra effort caused by debt; debt ceiling = maximum acceptable debt.
Big Ball of Mud โ no clear structure, everything depends on everything. Remedy: identify boundaries, extract modules, establish interfaces.
Distributed Monolith โ services must deploy together, sync chains, shared DBs. Remedy: merge related services, async communication, separate DBs.
Golden Hammer โ one solution for all problems, force-fitting patterns. Remedy: learn alternatives, evaluate objectively, prototype options.