Title here
Summary here
Status: Accepted Date: 2026-03-28 Supersedes: N/A Superseded by: N/A
The ztick scheduler needs a clean separation of concerns between business logic, adapters, and the interface layer to enable:
The project follows strict conventions to enforce these properties (CLAUDE.md), requiring a formal architecture decision to guide implementation.
| Option | Pros | Cons |
|---|---|---|
| Hexagonal (4 Layers) | Clear dependency direction; each layer independently testable; explicit adapters for all I/O | Requires discipline to maintain boundaries; 4 layers adds ceremony for tiny features |
| Layered (3 Layers) | Simpler for small projects; fewer boundaries | Harder to swap adapters; infrastructure often leaks into application |
| Flat/Monolithic | Fastest to initial implementation | No separation; hard to test; dependencies cycle; refactoring painful |
Adopt hexagonal architecture with 4 strict layers:
┌──────────────────────────────────┐
│ Interfaces (CLI, Config) │
├──────────────────────────────────┤
│ Infrastructure (TCP, Shell, Persistence) │
├──────────────────────────────────┤
│ Application (Scheduler, Storage) │
├──────────────────────────────────┤
│ Domain (Job, Rule, Runner) │
└──────────────────────────────────┘Dependency rule: Outer layers import from inner layers only. Inner layers NEVER import from outer.
src/domain/) — Pure types, zero dependenciessrc/application/) — Scheduler logic, depends on Domain onlysrc/infrastructure/) — Adapters (TCP, Shell, Persistence, Protocol), depends on Domain + Applicationsrc/interfaces/) — CLI entry point, Config, Wiring, depends on all layersWhat becomes easier:
What becomes harder:
| Principle | Status | Justification |
|---|---|---|
| Hexagonal Architecture (4 layers) | Compliant | All implementation adheres to this pattern; layer separation verified via import analysis |
| TDD (RED-GREEN-REFACTOR) | Compliant | Each layer includes co-located unit tests; 95%+ domain coverage |
| No ambiguous boundaries | Compliant | Each layer has a single responsibility; imports follow strict direction |
| Minimal Abstraction | Compliant | No interfaces without 2+ implementations; single canonical Runner union |
The Runner tagged union in src/domain/ defines the set of supported runner types. The table below tracks implementation status:
| Runner | Status |
|---|---|
| Shell | Implemented |
| HTTP | Implemented |
| AMQP | Implemented — see ADR-0005 for design decisions |
docs/development/architecture.md for code examplesdocs/ADR/0005-amqp-runner-design.md (AMQP runner design decisions)