ADR-003: Monolith-first backend
Context
The 5-layer pipeline (Generation → Execution → Analysis → Decision → Reporting) could be deployed as microservices from day one. However, with fewer than 10 customers expected in the first 6 months, the operational overhead of managing multiple services, service mesh, inter-service auth, and distributed tracing would slow development significantly.
The interface + adapter pattern (see .context/AI_RULES.md) ensures the monolith is extraction-ready: each layer communicates through interfaces with Local and Remote implementations. Switching from Local (in-process) to Remote (network call) is a config flag change, not a rewrite.
Decision
Start with a monolith backend where all 5 pipeline layers run in a single JVM process. Use the interface + adapter pattern so any layer can be extracted to its own service when scale demands it.
Alternatives considered
| Option | Pros | Cons |
|---|---|---|
| Monolith-first (chosen) | Simple deployment, no network overhead, faster iteration, one DB connection pool | Risk of tight coupling if discipline lapses |
| Microservices from day one | Independent scaling, technology diversity per layer | Operational complexity, distributed debugging, inter-service latency, premature for fewer than 10 customers |
| Modular monolith (no extraction path) | Simplest architecture | Risky if one layer needs independent scaling later |
Consequences
What becomes easier
- Single deployment unit: one Docker image, one Helm release
- Debugging is local — stack traces span all layers
- No inter-service auth, no service mesh, no distributed tracing (yet)
- Database transactions can span layers when needed
What becomes harder
- Must maintain interface boundaries with discipline (CI lint helps)
- All layers scale together — can't scale Analysis independently
- A bug in one layer can affect all layers
- Team must resist the temptation to take shortcuts across layer boundaries
Extraction trigger
Extract a layer to its own service when: (1) it needs independent scaling, or (2) the team grows to 5+ engineers working on different layers simultaneously.