ADR-0016: Replaceable Batteries and Shell Integration
- Status: Accepted
- Date: 2026-07-16
- Deciders: @revant.one
- Supersedes: N/A
- Superseded by: N/A
Context
When generic LLM coding assistants generate new applications (e.g., Helpdesk, CRM, or WMS), they often attempt to build redundant features such as custom login forms, user registration endpoints, custom user dashboards, or authentication databases. This leads to duplicate code, security vulnerabilities, and architectural fragmentation.
Framework M implements a "Replaceable Batteries" architecture. All baseline cross-cutting concerns—including authentication, authorization, session management, user profile settings, and the desk administration dashboard—are solved at the framework/platform layer and run within unified shell applications (such as framework-m or business-m).
Decision
We will enforce that all custom business applications are built as modular plugins that mount directly into the existing shell environments. Developer workflows and LLM coding assistants must strictly adhere to the following rules:
- Zero Custom Authentication/Registration:
- Custom applications must wire directly into the existing
AuthChainand utilizerequest.state.userfor current user sessions. - Do not implement custom login/signup forms, password reset endpoints, or OAuth adapters.
- Custom applications must wire directly into the existing
- Leverage the Project/App Shell:
- The user interface must compose directly into the targeted shell environment (such as the
business-mshell or the application's own custom shell, skipping/bypassingframework-m's default frontend shell). - UI elements must be built as Micro-Frontends (MFEs) that are registered via entry points and imported from
@framework-m/ui. - Do not build redundant standalone landing, login, or dashboard pages outside of the designated shell composition layer.
- The user interface must compose directly into the targeted shell environment (such as the
- Register via Platform Protocols:
- Custom database entities must inherit from
BaseDocTypeand pair with aBaseController. - Custom API routers, background jobs, and event bus subscribers must be declared using framework decorators (
@job,@rpc,@whitelist) and bootstrapped using the modularBootstrapProtocol. - Do not instantiate custom server runner classes (e.g. invoking
Litestar()) or hack the primary application factory (create_app()).
- Custom database entities must inherit from
Consequences
Positive
- Zero Hallucination Boilerplate: LLM code generation remains laser-focused on business domain logic rather than writing basic auth/dashboard boilerplate.
- Strict Decoupling: Applications are easily pluggable, testable, and hot-swappable across environments.
- Unified Security: Centralizes authentication and authorization in the standard framework adapters.
Negative
- Rigid Conventions: Third-party developers must learn and strictly follow the platform's module conventions.