A modular monolith enforces what a network boundary did not

Splitting into services enforces nothing if they share a database; splitting into modules with a checked dependency rule enforces more.

# deptrac.yaml
layers:
  - name: Orders
    collectors: [{ type: directory, value: app/Modules/Orders/.* }]
  - name: Catalogue
    collectors: [{ type: directory, value: app/Modules/Catalogue/.* }]
  - name: Shared
    collectors: [{ type: directory, value: app/Shared/.* }]

ruleset:
  Orders:    [Shared]      # NOT Catalogue
  Catalogue: [Shared]
  Shared:    ~

A build failure on a cross-module import is a stricter guarantee than a network call between two services that both connect to the same schema. It also fails at the moment the coupling is introduced rather than eighteen months later, which is the difference between a five-minute conversation and a refactor.