Problem
Architectural intent such as layering, latency budgets, or dependency rules lives in documents. Code drifts from it unnoticed until a costly failure. Reviews cannot catch everything.
Also known as: fitness-functions, architecture-tests
Automate objective checks that guard architectural characteristics so they cannot silently erode.
Architectural intent such as layering, latency budgets, or dependency rules lives in documents. Code drifts from it unnoticed until a costly failure. Reviews cannot catch everything.
A fitness function is any mechanism that gives an objective assessment of how close a system is to an architectural goal. The term comes from evolutionary computing and was applied to architecture by Ford, Parsons, and Kua.
Fitness functions fall into several types: atomic versus holistic, triggered versus continuous, and static versus dynamic. A unit-level dependency check is atomic and triggered. A load test of a whole flow is holistic. A production latency alert is continuous.
Pair each characteristic with a measurable check and a place to run it.
// ArchUnit-style dependency rule
noClasses().that().resideInAPackage("..domain..")
.should().dependOnClassesThat()
.resideInAPackage("..infrastructure..");
# production check
alert: p99_latency_checkout > 400ms for 10m
Start with the two or three characteristics that would hurt most if lost, such as module boundaries, data residency, and tail latency. Add a function only when a violation is both plausible and costly, and give each function an owner and a documented reason it exists.
Low - CI and monitoring reuse
Low to medium
Medium - choosing the right metrics
Checks pass while the real characteristic degrades
Flaky functions get ignored or disabled
Thresholds never updated after intentional redesign