Skip to content
Arxo Arxo

Smells

smells is the v2 architectural smell metric. It detects structural anti-patterns, adds optional temporal/co-change/SAT overlays, and emits a composite risk score.

  • Cycles (with severity buckets)
  • Hub-like modules
  • God components
  • Hierarchy smells (cyclic/deep/wide)
  • Dense structure
  • Ambiguous interfaces
  • Feature concentration and scattered functionality
  • Compound overlap risk across smell families
KeyMeaning
smells.cycles.countNumber of cyclic SCC components
smells.cycles.mild_countMild cycle count
smells.cycles.moderate_countModerate cycle count
smells.cycles.severe_countSevere cycle count
smells.cycles.max_sizeLargest cycle size
smells.hubs.countHub-like module count
smells.god_components.countGod component count
smells.hierarchy.cyclic_countCyclic hierarchy smell count
smells.hierarchy.deep_countDeep hierarchy smell count
smells.hierarchy.wide_countWide hierarchy smell count
smells.structure.dense_countDense-structure smell count
smells.interface.ambiguous_countAmbiguous-interface smell count
smells.feature.concentration_countFeature concentration smell count
smells.feature.scattered_countScattered functionality smell count
smells.compound.high_risk_module_countModules with multi-family high compound risk
smells.compound.overlap_indexOverlap index across smell families
smells.total.countTotal smell count across families
KeyMeaning
smells.temporal.available1 when temporal channel is available
smells.temporal.new_countNew smell fingerprints vs baseline
smells.temporal.resolved_countResolved smell fingerprints vs baseline
smells.temporal.persistent_countPersistent smell fingerprints vs baseline
smells.temporal.deltanew_count - resolved_count
smells.cochange.available1 when co-change channel is available
smells.cochange.overlap_ratioRatio of smelly modules that are high co-change coupled
smells.cochange.high_coupled_smelly_module_countCount of high-coupled smelly modules
smells.sat_overlap.available1 when SAT overlap channel is available
smells.sat_overlap.overlap_module_countSmelly modules overlapping SAT-source findings
smells.sat_overlap.overlap_ratioOverlap ratio for smelly modules
KeyMeaning
smells.risk.structuralStructural risk contribution
smells.risk.temporalTemporal contribution
smells.risk.cochangeCo-change contribution
smells.risk.sat_overlapSAT overlap contribution
smells.risk.overallOverall smells risk score (0..1)
smells.risk.confidenceConfidence in overall score (0..1)
ChannelRequiresauto behaviorforce behavior
TemporalBaseline report file (temporal.baseline_report_path)If missing/unreadable: unavailable (available=0)Metric run fails
Co-changeGit history signalsIf unavailable: unavailable (available=0)Metric run fails if git history cannot be loaded
SAT overlapFindings from shape_validation or effect_violationsIf no SAT source findings: unavailable (available=0)Metric run fails

off disables a channel entirely and emits available=0.

smells emits deterministic findings with stable rule IDs (for example: arxo/smells/cycles/component, arxo/smells/hubs/hub-like, arxo/smells/god-components/bottleneck).

metrics:
- id: smells
enabled: true
config:
top_k: 10
emit_findings: true
channels:
temporal_mode: auto # off | auto | force
cochange_mode: auto # off | auto | force
sat_mode: auto # off | auto | force
temporal:
baseline_report_path: ".arxo/baselines/smells_prev_report.json"
thresholds:
cycles:
severe_size: 6
moderate_min: 3
moderate_max: 5
hubs:
min_degree: 8
percentile: 0.90
adaptive: true
god_components:
min_degree: 10
betweenness: 0.10
adaptive_betweenness: true
hierarchy:
deep_depth: 6
wide_fanout: 8
structure:
dense_density: 0.12
interface:
ambiguous_min_exports: 20
ambiguous_min_fanout: 8
feature:
concentration_top_percent: 0.10
concentration_share_threshold: 0.35
scattered_entropy_threshold: 1.50
scattered_partner_groups_min: 3
risk_weights:
structural: 0.45
temporal: 0.20
cochange: 0.20
sat_overlap: 0.15
policy:
invariants:
- metric: smells.cycles.severe_count
op: "=="
value: 0
- metric: smells.hubs.count
op: "<="
value: 3
- metric: smells.risk.overall
op: "<="
value: 0.35

The following legacy keys were removed in v2:

  • smells.cyclic_dependency_count -> smells.cycles.count
  • smells.cyclic_dependency_severe -> smells.cycles.severe_count
  • smells.cyclic_dependency_moderate -> smells.cycles.moderate_count
  • smells.cyclic_dependency_mild -> smells.cycles.mild_count
  • smells.hub_like_count -> smells.hubs.count
  • smells.god_component_count -> smells.god_components.count
  • smells.total_smell_count -> smells.total.count
  • smells.unstable_dependencies_note -> smells.risk.overall