# ADR 0005: Strict Clean Architecture and Capability Modules ## Context Mastermind is a complex macOS application with multiple responsibilities: continuous capture, knowledge extraction, local graph management, and AI assistance. To ensure maintainability, testability, and clear ownership of privacy boundaries, we need a robust architectural structure. ## Decision We adopt a **Strict Clean Architecture** organized around **Capability Modules**. ### 1. Capability Modules The codebase is divided into stable capability boundaries: - **AppShell**: Orchestration, lifecycle, and composition root. - **Observation**: Collectors and raw evidence acquisition. - **Knowledge**: The Context Graph, projection, and retrieval logic. - **Assistant**: AI sessions, provider routing, and prompt management. - **Trust**: Activity logging, health monitoring, and privacy enforcement. - **Infrastructure**: Shared utilities, encryption, and low-level storage. ### 2. Strict Clean Architecture Each module follows Clean Architecture principles: - **Entities**: Pure domain models and logic (inner-most). - **Use Cases/Services**: Application-specific business rules. - **Interface Adapters**: Controllers, presenters, and gatekeepers. - **Frameworks & Drivers**: External tools like ScreenCaptureKit, SQLite, and sidecar clients (outer-most). ### 3. Compile-Time Dependency Rule - Dependencies flow **inwards**: outer layers depend on inner layers. - Modules communicate through **Application Ports** (protocols). - **Protocols are required** at module boundaries and for all I/O (adapters). - Internal module logic does not require protocols for every internal function or value type, avoiding unnecessary boilerplate. ### 4. Enforcement - Boundaries are enforced by separate Swift targets/modules where possible. - The **Composition Root** (in AppShell) is the only place where concrete adapters are instantiated and injected. ## Consequences - **Pros**: Clearer boundaries, easier to mock dependencies for testing, better isolation of sensitive data processing, and independent evolution of capabilities. - **Cons**: Higher initial setup cost for new modules and mandatory boilerplate for cross-module communication.