# ADR 0001: Govern as a Modular Monolith Status: Accepted Date: 2026-07-29 ## Context The application is deployed on a LAN NAS as one Docker container with a Python HTTP process, SQLite, a build-free browser client, scheduled refresh work, external market providers, and LLM features. Product breadth has grown, while routing, persistence, frontend state, and CSS remain concentrated in a few large files. The system may later become internet-facing, gain more features, replace SQLite, or move jobs to workers. It does not currently have load or team boundaries that justify distributed services. ## Decision Retain one deployable application and introduce strict internal modules, ports, adapters, feature registries, data contracts, repository contracts, and regression gates. The deployment remains: ```text one image + one application process + one persistent data volume + port 8765 ``` Internal code moves toward: ```text delivery -> application services -> ports -> infrastructure ``` Compatibility facades permit incremental migration. No feature is rewritten solely to match the target directory structure. ## Consequences ### Positive - Current NAS deployment stays simple. - Refactoring can proceed in reversible stages. - Feature ownership and account boundaries become visible. - Data, database, LLM, and job adapters can be replaced later. - A measured hotspot can be extracted without first untangling business logic. ### Costs - The transition temporarily contains old and new entrypoints. - Boundary tests and registries require ongoing maintenance. - A single process remains a capacity and fault-isolation limit until infrastructure is deliberately extracted. ## Rejected Alternatives ### Immediate microservices Rejected because they add network contracts, service discovery, deployment coordination, distributed tracing, and failure modes before load requires them. ### Full framework rewrite Rejected because replacing the HTTP and frontend frameworks while moving boundaries would combine structural and behavioral risk. ### Continue patching flat modules Rejected because current file size, direct provider creation, global page state, and CSS override layers already make regressions difficult to isolate. ## Revisit Conditions Reconsider service extraction when one module has independently measured scaling needs, requires a separate availability boundary, or needs an independent release lifecycle.