Skip to main content

ovecc diagnose

Named architectural smells at component (directory) granularity: cycles with per-hop file:line witness edges, hub-like and god components, zone of pain (Martin distance), dense structure, hotspots, unstable interfaces, change coupling, and modularity violations. Every finding carries evidence, the design principle it breaks, a deterministic confidence, a curated remediation, and a machine fix action. Deterministic — no patterns are invented.

Usage: ovecc diagnose [OPTIONS]

Example

$ ovecc diagnose
Diagnosis: 2 finding(s) — critical 0, high 0, medium 2, low 0

[Medium] Cyclic Dependency — component-group src/core <-> src/services (confidence 1.00)
Principle: Acyclic Dependencies Principle
Evidence: cycle_size=2 (>= 1), src/core/db.ts:2 — cycle_edge=1 (src/core -> src/services: ../services/billing), src/services/billing.ts:1 — cycle_edge=2 (src/services -> src/core: ../core/db)
Fix: Break the cycle: invert one dependency or extract the shared core both sides depend on. [Dependency Inversion / Extract shared module]
Action: break_cycle (auto-fixable: no)
When not to act: Type-only/deferred imports are excluded; a tightly cohesive cluster may be intentional.

[Medium] Unstable Dependency — component src/core (confidence 0.95)
Principle: Stable Dependencies Principle
Evidence: uphill_share=1 (>= 0.30), instability=0.25
Fix: Don't depend on something more likely to change than you: invert the dependency or introduce a stable abstraction. [Dependency Inversion / Introduce stable interface]
Action: invert_dependency (auto-fixable: no)
When not to act: Depending on a stable, well-versioned boundary is fine.

An empty diagnosis is explicit: Diagnosis: 0 finding(s) with per-severity counts.

Anatomy of a finding

FieldMeaning
Detector + componentWhich smell, where (directory granularity)
PrincipleThe established design principle it violates
EvidenceThe metric values and file:line edges that triggered it — with the thresholds shown inline
ConfidenceDeterministic 0–1 score derived from how far past the threshold the evidence is
FixA curated remediation, with the pattern name in brackets
ActionMachine-readable remediation id (consumed by agents)
When not to actThe honest escape hatch: cases where the smell is intentional

Options

OptionEffect
--target <substr>Scope to findings touching this file or module
--severity <level>Only findings at or above this severity
--group-by <family|severity|component>Group the text/markdown report — family is structural / stability / size / evolutionary
--fail-on <medium|high|any>Exit 1 when a finding crosses the threshold

Plus the global options. Formats additionally include sarif and codeclimate.

Detector families

  • Structural — cyclic dependencies, hub-like components, dense structure
  • Stability — unstable dependencies, zone of pain (distance from the main sequence), unstable interfaces
  • Size — god components
  • Evolutionary — hotspots, change coupling (requires Git history)

Thresholds are tunable via [diagnose] min_confidence in the configuration.

  • advise — the same findings scoped to one target
  • metrics — the raw numbers the detectors read