CONCEPT Cited by 1 source
Architectural fitness function¶
Definition¶
An architectural fitness function is a machine-executable test that asserts an architectural rule about a codebase, run continuously in CI to catch deviations at the moment they occur rather than at architecture-review time. The term originates with Neal Ford, Rebecca Parsons, and Patrick Kua's Building Evolutionary Architectures (2017), which framed "any objective function used to assess how close a given design solution is to achieving a set aim" as the core lever for keeping evolving codebases aligned with architectural intent.
The wiki's first canonical citation is via Netflix's Nebula ArchRules post, where 358+ fitness functions run across 5,000+ repositories in CI on every main-branch build, detecting nearly 1 million issues.
Examples of architectural fitness functions¶
- Layering: "No class in
com.example.webmay depend on a class incom.example.persistencedirectly — only viacom.example.service." - Cyclic-dependency-free: "No package may participate in a dependency cycle with another package."
- Naming convention: "All classes implementing
Repositorymust reside in a package ending in.persistenceand have a name ending inRepository." - API surface stability (the Netflix case study): "No class
outside this library's package may call into a class inside
this library's package that is annotated
@Deprecatedor not annotated@Public." See patterns/api-stability-annotations. - CVE avoidance: "No class may call any method on
org.apache.log4j.Logger" (sample fitness function for the Log4Shell CVE response). - Cross-cutting: "No JPA
@Entityclass may have a public setter."
The structural common thread: the rule expresses an architectural invariant that should hold across the codebase, and is checkable mechanically without human review.
Distinguishing properties (per Netflix's analysis)¶
The Netflix ArchRules post articulates three properties that a high-quality fitness- function tool needs:
- Bytecode (or equivalent) over AST — rules must operate at a layer that survives syntactic sugar and works across JVM languages. See concepts/bytecode-vs-ast-static-analysis.
- Type-safe rule API with IDE support — rules should be written as code (testable, version-controllable, refactorable) not as opaque XPath/regex strings.
- Class-graph retention — rules need access to the full classpath graph (call sites, inheritance, annotations) to express cross-class invariants.
These three properties are what make ArchUnit the canonical fitness-function substrate on the JVM.
The dashboarding inversion¶
Traditional fitness-function deployments treat rule failures as build-blocking — fail-the-build is the default remediation-forcing function. Netflix's ArchRules deployment at fleet scale (358 rules × 5,000 repos × ~1M issues) is too large for build-blocking to be the primary mode. Instead:
"Our internal Nebula standard Gradle wrapper and plugin suite automatically enable the ArchRules runner on every project, and provides a custom reporter which sends the report data to our Internal Developer Portal on every main-branch CI build. This way, library authors can easily see a report of all downstream consumers using their experimental, deprecated, or non-public APIs, giving them confidence to make 'breaking' changes, knowing that it will not actually break downstream consumers." — sources/2026-05-08-netflix-scaling-archunit-with-nebula-archrules
The fitness-function output is a dashboard, not a build gate. Build-blocking is reserved for high-priority rules ("about 1,000 of these issues are for 'High' priority rules" out of ~1M); the rest are tracked-and-prioritized signals, not blockers. See patterns/build-time-tech-debt-detection for the operational pattern.
Distinct from linting¶
| Aspect | Lint | Fitness function |
|---|---|---|
| Granularity | Per-file or per-statement | Per-codebase architectural invariant |
| Scope | Style, common bugs | Architectural intent |
| Class-graph awareness | No | Yes |
| Cross-cutting rules | Limited | Native |
| Failure mode | Per-file warning | Build status / dashboard |
Lint catches style issues; fitness functions catch architectural drift. There's overlap (e.g. "don't import this package" could be either), but the framing is different.
Distinct from architecture review¶
Architecture review is synchronous, human-mediated, and periodic — quarterly review of new designs, ad-hoc review of migration plans. Fitness functions are continuous, automated, and per-commit. The two are complementary: review establishes the rules; fitness functions enforce them mechanically.
When to use¶
- The architectural invariant is stable enough to encode as a rule (won't change every sprint).
- The codebase is large enough that human review can't catch every violation.
- The rule's false-positive rate is low (stable enough to block builds or trigger high-priority alerts).
- The rule's fix is reasonably actionable (you know what to do when it fires).
When not to use¶
- The invariant is in flux / under design — premature encoding adds churn.
- The rule has a high false-positive rate — it becomes noise that engineers ignore.
- The fix is unclear — the rule reports problems engineers can't address.
Seen in¶
- sources/2026-05-08-netflix-scaling-archunit-with-nebula-archrules — Netflix's 358-rule × 5,000-repo deployment is the canonical wiki instance of architectural fitness functions at fleet scale.