|
| 1 | +[importlinter] |
| 2 | +root_package = orb |
| 3 | +include_external_packages = True |
| 4 | + |
| 5 | +# --------------------------------------------------------------------------- |
| 6 | +# Contract 1: domain-is-clean |
| 7 | +# |
| 8 | +# The domain layer must not import from any outer layer or from CLI/UI |
| 9 | +# frameworks (argparse, etc.). This is the strictest contract — any new |
| 10 | +# violation here is a clean-architecture regression. |
| 11 | +# |
| 12 | +# NOTE: allow_indirect_imports = True is required because import-linter |
| 13 | +# resolves the root `orb` package as an intermediate node when any domain |
| 14 | +# module does `from orb.domain...`. The root orb/__init__.py re-exports |
| 15 | +# SDK/bootstrap symbols which transitively touch outer layers, creating |
| 16 | +# false positives on every domain file. Direct-only enforcement is the |
| 17 | +# correct policy here. |
| 18 | +# --------------------------------------------------------------------------- |
| 19 | +[importlinter:contract:domain-is-clean] |
| 20 | +name = Domain layer is clean (no outer-layer imports) |
| 21 | +type = forbidden |
| 22 | +source_modules = orb.domain |
| 23 | +forbidden_modules = |
| 24 | + orb.application |
| 25 | + orb.infrastructure |
| 26 | + orb.interface |
| 27 | + orb.providers |
| 28 | + orb.monitoring |
| 29 | + orb.cli |
| 30 | + argparse |
| 31 | +allow_indirect_imports = True |
| 32 | +# No baseline ignore_imports needed: the only domain argparse violation |
| 33 | +# (provider_cli_spec_port) was moved to orb.providers.base in this branch (E2). |
| 34 | +# Any future argparse-in-domain import is now a real CI failure. |
| 35 | + |
| 36 | + |
| 37 | +# --------------------------------------------------------------------------- |
| 38 | +# Contract 2: application-no-infra-concretes |
| 39 | +# |
| 40 | +# The application layer must not import from infrastructure concretes, |
| 41 | +# provider implementations, or monitoring adapters. It may only depend on |
| 42 | +# domain (pure) and its own cross-cutting application interfaces. |
| 43 | +# |
| 44 | +# All A1/A2/A3 baseline violations have been fixed by Epic E4 / ticket #1358: |
| 45 | +# A1 — TemplateDTO moved to orb.application.dto.template |
| 46 | +# A2 — same fix as A1 |
| 47 | +# A3 — MetricsCollector now injected via MetricsPort |
| 48 | +# --------------------------------------------------------------------------- |
| 49 | +[importlinter:contract:application-no-infra-concretes] |
| 50 | +name = Application layer does not import infrastructure concretes |
| 51 | +type = forbidden |
| 52 | +source_modules = orb.application |
| 53 | +forbidden_modules = |
| 54 | + orb.infrastructure |
| 55 | + orb.providers |
| 56 | + orb.monitoring |
| 57 | +allow_indirect_imports = True |
| 58 | + |
| 59 | + |
| 60 | +# --------------------------------------------------------------------------- |
| 61 | +# Contract 3: infrastructure-no-upward |
| 62 | +# |
| 63 | +# The infrastructure layer must not import from the interface/CLI layers. |
| 64 | +# It adapts domain ports to external systems; it must not depend on the |
| 65 | +# presentation/CLI tier. |
| 66 | +# |
| 67 | +# I1 baseline violation has been fixed by Epic E4 / ticket #1358: |
| 68 | +# I1 — console_adapter inverted: it now owns Rich logic and cli/console.py |
| 69 | +# delegates downward to the adapter (cli → infrastructure, correct). |
| 70 | +# --------------------------------------------------------------------------- |
| 71 | +[importlinter:contract:infrastructure-no-upward] |
| 72 | +name = Infrastructure layer does not import upward layers |
| 73 | +type = forbidden |
| 74 | +source_modules = orb.infrastructure |
| 75 | +forbidden_modules = |
| 76 | + orb.interface |
| 77 | + orb.cli |
| 78 | +allow_indirect_imports = True |
0 commit comments