three-layer-stack-has-clean-boundaries

IN derived (depth 1)

The architecture enforces strict layer separation: pure data model at bottom, context-managed API with dict returns in the middle, and pure-formatter CLI at the top

Summary

Each layer of the codebase has a single, well-defined responsibility and communicates with adjacent layers through narrow interfaces. The data model defines structures without logic, the API layer handles all mutation atomically through a context manager, and the CLI only formats output. This means changes to one layer are unlikely to ripple into others, and each layer can be tested or replaced independently.

Justifications

SL — Each layer's purity constraint (no behavior, load-save atomicity, no business logic) prevents cross-layer coupling

Antecedents (all must be IN):

  • three-layer-architecture — The codebase is a three-layer stack: data model (`__init__.py`), TMS engine (`network.py`), and persistence (`storage.py`), with `api.py` providing functional API and `cli.py` as a thin argparse wrapper.
  • init-is-pure-data-model — `reasons_lib/__init__.py` contains only dataclass definitions (`Node`, `Justification`, `Nogood`) with no behavior, validation, or I/O; it imports nothing from the project and sits at the bottom of the import graph.
  • api-uses-with-network-context-manager — `api.py` uses a `_with_network` context manager to ensure load-operate-save atomicity for all network mutations.
  • cli-is-pure-formatter — Every cmd_* function delegates to api.* and only formats the returned dict for terminal output; no business logic lives in the CLI layer.

Dependents

These beliefs depend on this one:

Details