Skip to content
Arxo Arxo

Metrics Overview

Arxo provides a comprehensive suite of architecture metrics organized into six categories. Each metric produces numeric values you can track over time and enforce with policy invariants.

Understand how your code is organized: are there circular dependencies? Which modules are critical? Is the codebase layered cleanly?

How far do changes ripple? Where are the dependency bottlenecks? These metrics help you keep modules loosely connected.

Analyze your Git history to see which files change together, who owns what, and where instability is hiding.

Spot architectural problems early: god modules, unstable packages, fragile single-points-of-failure, and complexity hotspots.

Architecture guardrails for LLM integrations.

Architecture guardrails for ML training, serving, and MLOps controls.

Architecture guardrails for LLM fine-tuning pipelines.

Architecture guardrails for retrieval-augmented generation systems.

Architecture guardrails for multi-agent orchestration and tool-calling systems.

Summary scores and concrete recommendations that tell you what to fix and where to start.


New to Arxo? Start with these three metrics to get a complete picture:


MetricWhat it measuresGood valueBad value
scc.max_cycle_sizeLargest cycle size0 (no cycles)> 5 modules
scc.component_countNumber of independent componentsHigh (= module count)Low (many modules merged into cycles)
centrality.module.max_fan_outMost dependencies from a single module< 10> 20
centrality.module.max_fan_inMost dependents on a single module< 15> 30
centrality.module.hub_like_countModules with both many dependents and dependencies0> 3
centrality.module.betweenness_maxHow much traffic flows through the busiest module< 0.30> 0.60
hierarchy.module.edge.upward_weight_ratioShare of dependency weight going upward/lateral<= 0.05> 0.15
hierarchy.module.agony.weighted_depth_normalizedWeighted hierarchy erosion normalized by depth<= 0.08> 0.15
hierarchy.module.edge.skip_layer_ratioShare of edges skipping intermediate layers<= 0.10> 0.20
modularity.module.best_qCommunity separation quality>= 0.30< 0.20
modularity.module.singleton_community_ratioPartition fragmentation<= 0.30> 0.40
modularity.module.boundary_edge_ratioCross-community dependency share<= 0.55> 0.70
MetricWhat it measuresGood valueBad value
propagation_cost.system.ratioHow far changes can ripple (0–1)< 0.10> 0.40
coupling_analysis.risk_indexComposite module coupling risk (0–1)< 0.35> 0.60
flow_analysis.graph.densityHow interconnected the directed dependency graph is< 0.10> 0.30
flow_analysis.graph.max_fan_in_weightHighest inbound dependency weight for one module< 10> 25
flow_analysis.graph.flow_hierarchyDAG-likeness of flow (higher means fewer cycle edges)> 0.80< 0.60

These are interpretation bands. Default propagation_cost finding thresholds are intentionally stricter for alerting (system_high: 0.5, system_critical: 0.7) to reduce noise.

MetricWhat it measuresGood valueBad value
l1.risk.overallOverall architecture risk score< 0.30> 0.60
l1.risk.structureStructure sub-score< 0.30> 0.60

Source Code
Import Graph ──► Grouping (file / folder / package)
├─ Structure & Organization
│ ├──► Circular Dependencies (cycles)
│ ├──► Critical Modules (fan-in, fan-out, hubs)
│ ├──► Layer Structure, Module Boundaries, Core vs Periphery
├─ Dependencies & Coupling
│ ├──► Change Impact (propagation cost)
│ └──► Dependency Bottlenecks
├─ Code Health
│ ├──► Code Smells, Package Health
│ └──► Architecture Resilience, Complexity Hotspots
└─ Insights & Actions
├──► Cross-Metric Insights (combines all of the above)
└──► Refactoring Suggestions (what to fix)

Structure, Dependencies, and Code Health metrics run independently in parallel. Insights & Actions runs after — it reads all the results and produces summary scores and recommendations.


Goal: Keep services loosely coupled and cycle-free.

metrics:
- id: scc
- id: propagation_cost
- id: centrality
- id: fsd_architecture
policy:
invariants:
- metric: scc.max_cycle_size
op: "=="
value: 0
message: "No circular dependencies between services"
- metric: propagation_cost.system.ratio
op: "<="
value: 0.15
message: "Services must stay loosely coupled"

Goal: Enforce layer boundaries and keep module coupling low.

data:
import_graph:
group_by: folder
group_depth: 2
metrics:
- id: scc
- id: propagation_cost
- id: centrality
- id: fsd_architecture
policy:
invariants:
- metric: scc.max_cycle_size
op: "=="
value: 0
- metric: centrality.module.hub_like_count
op: "=="
value: 0
message: "No god modules allowed"
- metric: fsd.public_api_bypass_count
op: "=="
value: 0
message: "Do not bypass slice public APIs"

Goal: Fast pass/fail check on every pull request.

metrics:
- id: scc
policy:
invariants:
- metric: scc.max_cycle_size
op: "=="
value: 0
Terminal window
arxo analyze --preset quick --fail-fast

Presets control which metrics run. For the core metrics:

PresetIncluded metricsTypical time
quickSCC, L1 Overview, Centrality1–5 seconds
fullAll available metricsVaries by project size
Terminal window
# Fast feedback
arxo analyze --preset quick
# Everything
arxo analyze --preset full

See Presets for the full list of available presets.


  1. Track trends, not just absolutes — A propagation_cost.system.ratio of 0.12 is fine on its own; what matters is whether it’s growing or shrinking over time.
  2. Group by folder, not file — File-level graphs are noisy. Use group_by: folder with group_depth: 2 for meaningful module boundaries.
  3. Combine metrics — SCC tells you if there are cycles; Centrality tells you which modules are critical; Propagation Cost tells you how far changes reach. Together they give a complete picture.
  4. Start strict, relax later — Set scc.max_cycle_size == 0 from day one. It’s much harder to remove cycles than to prevent them.
  5. Focus on fan-out first — High fan-out modules are the easiest to refactor (extract shared dependencies) and yield the biggest coupling reduction.