ADR-0001 - Three-layer architecture
ADR-0001 - Three-layer architecture #
- Status: Accepted (Context widened by ADR-0008; third-layer directory renamed
apps/→systems/by ADR-0009) - Date: 2026-05-07
- Deciders: Natan
Context #
The runner needs to verify multiple aspects of the Snappy stack across environments. Two competing pressures shape the layout:
- Capabilities outlive flows. "Is the S3 bucket reachable?" is a
question we'll ask in many contexts. The probe should live somewhere reusable.
- Flows are app-specific. "Run preflight, then data probes, then
behavioural tests" is unique to one app and doesn't generalise.
We considered three options:
- Flat (one folder) - capability and composition code intermingled.
Quickly tangles; the next app copy-pastes.
- Five layers (probes / checks / segments / flows / orchestrators)
- boundaries blur, "where does this go?" gets two valid answers.
- Three layers -
lib(shared infra) →components(per-system
capabilities) → apps (compositions).
Decision #
Adopt three layers:
src/
├── lib/ shared infrastructure (logger, tracer, formatters)
├── components/ per-system capabilities (one folder per system)
└── apps/ flow compositions (one folder per app)Each layer has a single responsibility. The decision tree:
- Operates on no system in particular →
lib/ - Operates on exactly one external system →
components/<system>/ - Decides ordering / composes other things →
apps/<app>/
Consequences #
- Pro: One obvious answer for where any new code goes.
- Pro: Components are reusable across apps (same
s3.readyusable
from snappy-api and a future conveyor app).
- Pro: Apps stay thin and declarative (read like a table of contents).
- Con: Two-file minimum to add a probe (component + app wiring).
Acceptable - composition is the value.
- Falsifiability: Revisit if either (a) we end up with components
that touch multiple systems, or (b) apps grow non-trivial logic outside step() calls. Either signals the wrong split.
See also #
explanation, with the decision tree and runtime composition.
Was this page helpful?