ADR-0001 — Modular monolith with detached workers¶
Status: Accepted · Date: 2026-08-03
Context¶
The system has clearly separable concerns — ingestion, compliance, agents, trading, risk, backtesting — and the reflex for a system with a dozen named components is to make each one a service. The deployment target, however, is a single user's laptop or home server, occasionally a small VPS.
Decision¶
Build a modular monolith: one deployable application containing the domain modules, with long-running and scheduled work as detached worker processes running the same codebase. Module boundaries are enforced in-process by explicit interfaces and an import-direction rule checked in CI.
Rationale¶
Microservices buy independent scaling and independent deployment. Neither is needed here: there is one user, one release cadence, and the load is bounded by a universe of a few thousand instruments on a daily cycle.
What they cost is substantial at this scale — distributed transactions across the ledger and compliance state, N deployment units on a machine that may be a laptop, network failure modes between components that would otherwise be function calls, and debugging that requires correlating traces across processes to answer questions a stack trace would have answered.
The specific risk of a monolith — that boundaries erode until extraction is impossible — is addressed directly. packages/domain may not import from packages/data, packages/agents, or apps/; dependencies point inward; import-linter fails the build otherwise. An architectural rule that is not enforced is an aspiration, and aspirations do not survive deadlines.
Consequences¶
Positive. One process to run and debug. Transactional consistency across domain state without distributed coordination. Shared types with no serialisation boundary. A laptop deployment that is genuinely realistic.
Negative. Everything scales together. A memory leak anywhere affects everything. Language choice is uniform, so the Rust extraction path (02 §1) becomes an extension module rather than a service.
Accepted risk. If the system ever needed multi-tenancy, extraction would be required. Multi-tenancy is explicitly out of scope (00 §4) for regulatory reasons that are independent of this decision, so the risk is largely theoretical.