Smells and metrics
Once you’ve recovered components (see Architecture recovery), the next question is whether the structure you got back is any good. Two different tools answer that, and they answer it differently:
- Smells locate. An architectural smell is a specific, nameable structural warning sign — something is wrong here, in this component, for this reason. Smells give you a place to look.
- Metrics track. A metric is a number computed over the whole architecture — how cohesive a component is internally, how coupled it is to everything else. Metrics don’t point at a spot; they tell you whether the overall shape is getting better or worse, commit over commit.
Four smells show up often enough to be worth knowing by name:
- Dependency Cycle — component A depends on B, which depends back on A (directly, or through a longer chain). Cycles make it impossible to reason about, build, or test one component in isolation from the other.
- Concern Overload — a component that has taken on too many unrelated responsibilities. It keeps growing because it’s the easiest place to bolt on “just one more thing.”
- Scattered Parasitic Functionality — logic that belongs to one concern but got implemented piecemeal across several components instead of living in one place.
- Link/Upstream Overload — a component with an unusually large number of things depending on it (or that it depends on), making it a de facto bottleneck for change.
The diagram below shows two of these in a simplified OS: a dependency cycle on the left, and a concern-overload hub on the right.
Simplified — illustrative, not a complete architecture.
Smells are yes/no, here-or-not-here findings. Metrics are the numbers underneath them — the same signals a smell reports on, but continuous instead of a threshold trip, which is what makes them useful for tracking a trend rather than just catching a single bad state:
- RCI (Ratio of Cohesive Interactions) — higher means a component’s internals talk to each other more than they talk outward.
- TurboMQ / BasicMQ — modularization quality scores; higher means the overall decomposition is doing its job of maximizing internal cohesion relative to external coupling.
- IntraConnectivity — average internal connection density per component; higher is better.
- InterConnectivity — average external coupling density between components; lower is better.
- TwoWayPairRatio — the fraction of dependencies that go both directions between two components; lower means cleaner, more one-directional layering.
A component can trip a smell today and still look fine on the metrics — one bad cycle in an otherwise clean component won’t tank its cohesion score. That’s expected: smells catch discrete structural problems, metrics catch a slower kind of erosion. You want both.
In arcade-agent: detect_smells reports the four smells above per component; compute_metrics
computes the six metrics above for a recovered architecture. See
Agent tools for both. For the exact formula behind each metric,
its range and direction, and a worked example from arcade-agent’s own self-analysis, see the
metrics reference →.