Technical Article

Architecture Rules Only Work When They Are Executable

"Domain code must never depend on infrastructure."

"Feature modules should never import each other's internal implementation details."

These are excellent architectural principles. But if the build still succeeds when someone violates them, they are not actually rules. They are mere suggestions.

Embedding Architecture into the Toolchain

Architectural guidelines documented only in wikis or diagrams inevitably decay under daily delivery pressure. A more resilient approach makes architectural boundaries an active part of the automated toolchain:

  • Explicit dependency graphs: Formalize allowed import directions between modules.
  • Lint and boundary rules: Use automated linters and dependency checks to block forbidden imports.
  • Public module APIs: Restrict module entry points through index exports or explicit public boundaries.
  • Boundary integration tests: Write automated assertions verifying that architectural invariants remain intact.
  • Continuous Integration gates: Fail the pipeline immediately whenever a disallowed dependency is introduced.

With these mechanisms in place, feedback is immediate and mechanical. Developers do not need to rely on the memory of an architecture diagram from months ago.

Enforcing Directional Dependencies

The toolchain can strictly enforce valid dependency flows:

domain → application → infrastructure

While immediately rejecting invalid shortcuts:

domain → infrastructure

This automated enforcement becomes indispensable as engineering teams scale. Without automated guards, each temporary shortcut introduces an unmonitored exception. Over time, the documented architecture and the real production codebase inevitably drift apart.

Properties of Effective Architectural Guardrails

Documentation remains valuable because it captures the rationale—the why behind a boundary. But automation guarantees that the boundary actually survives daily development pressure.

Effective architectural rules share three core characteristics:

  • Easy to understand: The rule's intention and failure messages are unambiguous.
  • Cheap to verify: Checks execute in seconds as part of the standard lint or test run.
  • Hard to circumvent: Bypassing the check requires an explicit, auditable exception.

If an architectural principle is important enough to shape the design of your system, it is important enough to be verified automatically. Architecture becomes enduring when the build system knows the rules too.