# ADR 0015 — Module boundaries enforced mechanically by `import-linter` layered contracts | | | |---|---| | **Status** | **Accepted** — 2026-07-30 | | **Scope** | How the modular monolith's module boundaries are made real: the tier model, the dependency rules, the mechanism that fails a build on violation, and the two escape hatches that are allowed. Does not choose the module inventory itself (`_decisions.md` Part 1, module lists) | | **Owner** | Talha Ahmed owns `.importlinter`, the tier assignment of every module and the review of any contract change. Ahmed Mujtaba owns the `service.py`/`dto.py` facade scaffolding per module and the boundary-violation test — including the deliberately-violating fixture that proves the gate fails — with a Talha review checkpoint | | **Consistent with** | `_decisions.md` Part 1 → *Module boundary enforcement and dependency rules* (all five rules), *Architecture style*, *AI boundary: how explainability, reviewability and 'never auto-reject' are enforced structurally*, *Testing, CI and delivery process* | | **Related ADRs** | 0001 (the monolith whose boundaries these are), 0011 (rule 3 is what makes "AI never auto-rejects" structural), 0009 (`identity` as an ambient dependency and the single authorization chokepoint), 0016 (the CI that runs the contracts), 0013 (the frontend analogue of the same argument) | --- ## Context A modular monolith without mechanical enforcement becomes a big ball of mud in about six months. That is a general claim, so here is the specific one: **this repository already demonstrates the failure mode at 4,779 lines of JavaScript.** | Prototype fact | Evidence | What it produced | |---|---|---| | Every module is a global on `window` — `DB`, `UI`, `Charts`, `App`, `Router`, `Views`, plus per-module globals. 22 ordered `