4.7 KiB
Software Architecture
For Claude: This content is mirrored in
skills/software-architecture/SKILL.mdwhich is auto-triggered when relevant. You don't need to load this file directly.
This document describes the architectural patterns we use to achieve our architecture beliefs. It serves as human-readable organizational documentation.
Beliefs to Patterns
| Belief | Primary Pattern | Supporting Patterns |
|---|---|---|
| Auditability by default | Event Sourcing | Immutable events, temporal queries |
| Business language in code | Domain-Driven Design | Ubiquitous language, aggregates, bounded contexts |
| Independent evolution | Event-driven communication | Bounded contexts, published language |
| Explicit over implicit | Commands and Events | Domain events, clear intent |
Event Sourcing
Achieves: Auditability by default
Instead of storing current state, we store the sequence of events that led to it.
Core concepts:
- Events are immutable facts about what happened, named in past tense:
OrderPlaced,PaymentReceived - State is derived by replaying events, not stored directly
- Event store is append-only - history is never modified
Why this matters:
- Complete audit trail for free
- Debug by replaying history
- Answer "what was the state at time X?"
- Recover from bugs by fixing logic and replaying
Trade-offs:
- More complex than CRUD for simple cases
- Requires thinking in events, not state
- Eventually consistent read models
Domain-Driven Design
Achieves: Business language in code
The domain model reflects how the business thinks and talks.
Core concepts:
- Ubiquitous language - same terms in code, conversations, and documentation
- Bounded contexts - explicit boundaries where terms have consistent meaning
- Aggregates - clusters of objects that change together, with one root entity
- Domain events - capture what happened in business terms
Why this matters:
- Domain experts can read and validate the model
- New team members learn the domain through code
- Changes in business rules map clearly to code changes
Trade-offs:
- Upfront investment in understanding the domain
- Boundaries may need to shift as understanding grows
- Overkill for pure technical/infrastructure code
Event-Driven Communication
Achieves: Independent evolution
Services communicate by publishing events, not calling each other directly.
Core concepts:
- Publish events when something important happens
- Subscribe to events you care about
- No direct dependencies between publisher and subscriber
- Eventual consistency - accept that not everything updates instantly
Why this matters:
- Add new services without changing existing ones
- Services can be deployed independently
- Natural resilience - if a subscriber is down, events queue
Trade-offs:
- Harder to trace request flow
- Eventual consistency requires different thinking
- Need infrastructure for reliable event delivery
Commands and Events
Achieves: Explicit over implicit
Distinguish between requests (commands) and facts (events).
Core concepts:
- Commands express intent:
PlaceOrder,CancelSubscription - Commands can be rejected (validation, business rules)
- Events express facts:
OrderPlaced,SubscriptionCancelled - Events are immutable - what happened, happened
Why this matters:
- Clear separation of "trying to do X" vs "X happened"
- Commands validate, events just record
- Enables replay - reprocess events with new logic
When to Diverge
These patterns are defaults, not mandates. Diverge intentionally when:
- Simplicity wins - a simple CRUD endpoint doesn't need event sourcing
- Performance requires it - sometimes synchronous calls are necessary
- Team context - patterns the team doesn't understand cause more harm than good
- Prototyping - validate ideas before investing in full architecture
When diverging, document the decision in the project's vision.md (see below).
Project-Level Architecture
Each project should document its architectural choices in vision.md under an Architecture section:
## Architecture
This project follows organization architecture patterns.
### Alignment
- Event sourcing for [which aggregates/domains]
- Bounded contexts: [list contexts and their responsibilities]
- Event-driven communication between [which services]
### Intentional Divergences
| Area | Standard Pattern | What We Do Instead | Why |
|------|------------------|-------------------|-----|
| [area] | [expected pattern] | [actual approach] | [reasoning] |
This creates traceability: org beliefs → patterns → project decisions.