methodology-balanced-coupling

star 0

Assess coupling with the Balanced Coupling model (integration strength, distance, volatility). Use when judging whether coupling is balanced or risky, scoring the coupling_balance dimension, or deciding what to flag as structural risk. Highest risk is high strength + high distance + high volatility together. NOT generic "decouple everything" advice. NOT for assigning the score itself (use architecture-scorecard) or for executable checks (use methodology-architecture-fitness).

alexei-led By alexei-led schedule Updated 6/6/2026

name: methodology-balanced-coupling description: >- Assess coupling with the Balanced Coupling model (integration strength, distance, volatility). Use when judging whether coupling is balanced or risky, scoring the coupling_balance dimension, or deciding what to flag as structural risk. Highest risk is high strength + high distance + high volatility together. NOT generic "decouple everything" advice. NOT for assigning the score itself (use architecture-scorecard) or for executable checks (use methodology-architecture-fitness).

Balanced Coupling

A model for judging whether coupling between components is a problem or not. Coupling is not the enemy — it is what makes a system more than its parts. The question is never "is this coupled?" but "is this coupling balanced?"

This skill summarizes Vlad Khononov's model in our own words and maps it onto the scorecard. For attribution and licensing, see references/attribution.md. Do not paste, quote, closely paraphrase, or copy tables/diagrams from the source.

When to use

Use when judging whether a coupling relationship is a problem — scoring the coupling_balance dimension, deciding what to flag as structural risk, designing module boundaries, or sanity-checking a "decouple this" recommendation. The architecture-review and architecture-design skills reach for this when they find two components that share knowledge and ask whether that sharing is balanced. Not for assigning the score itself (architecture-scorecard) or for executable enforcement (methodology-architecture-fitness).

Skill navigation

  • Missing relationship evidence: return to architecture-review for observed code or architecture-design for proposed boundaries.
  • Current skill: use methodology-balanced-coupling to classify strength, distance, volatility, severity, and balancing move.
  • Next skill: use architecture-scorecard when scoring a review, architecture-design when revising target boundaries, or architecture-plan only when sequencing an approved balancing move.

The three dimensions

Evaluate the connection between two components, not the components. Three dimensions, each answering a different question.

  1. Integration strength — how much knowledge the components share, which sets the likelihood a change in one forces a change in the other. Four levels, strongest to weakest:

    • Intrusive — integration through private internals: shared databases, undocumented APIs, implementation details. Fragile and often implicit; the intruded component may not know it is depended on.
    • Functional — components share business requirements and must change together when requirements do. Duplicated business rules across frontend/backend is the classic implicit case.
    • Model — components share a domain model; a model change ripples to all sharers.
    • Contract — integration through an explicit, stable contract that hides internals (facade, published language, anti-corruption layer, DTOs). Lowest shared knowledge. The goal for high-distance integration.
  2. Distance — how far apart the components sit, which sets the cost of a cascading change. Rises through levels of abstraction: methods → objects → packages → services → systems. It is relative to the level you analyze — at any level, the highest distance is that level's own boundary. Two modules in one deployable can still be "high distance" relative to each other. It is socio-technical: two services owned by different teams are further apart than the same two owned by one team. Runtime coupling counts too — synchronous calls bind lifecycles tighter than async messaging.

  3. Volatility — how likely a component is to change at all. Unbalanced coupling that never changes causes no pain. Estimate from the business domain first; use commit history only as supporting churn/change-locality evidence because poor design can inflate or suppress commit frequency:

    • Core subdomain (competitive advantage) → high volatility.
    • Supporting subdomain (needed, not differentiating) → low volatility.
    • Generic subdomain (solved problem, off-the-shelf) → low functional volatility, but watch implementation volatility (swapping a provider).

    Volatility is a property of the upstream component. A stable component that must change alongside a volatile one inherits inferred volatility — score it by the most volatile thing it changes with, not by its own subdomain alone. Propagate inferred volatility along dependency edges.

Explain DDD terms in plain language on first use — do not assume the user knows "core subdomain."

The balance rule

Modularity emerges when strength and distance counterbalance — one high, the other low. Complexity emerges when they match — both high or both low.

  • High strength + low distance = high cohesion (good). Things that change together live together; cascades are cheap.
  • Low strength + high distance = loose coupling (good). Far apart, but they barely share knowledge, so cascades are rare.
  • Low strength + low distance = low cohesion. Unrelated things crammed together; drifts toward a big ball of mud.
  • High strength + high distance = tight coupling. Frequent cascades that are expensive to make. A step toward a distributed monolith.

Read it two ways. The quick read is a binary rule:

BALANCE = (STRENGTH XOR DISTANCE) OR NOT VOLATILITY

Acceptable when strength and distance counterbalance, or when the relationship won't change. The graded read scores each dimension 1–10 from evidence:

BALANCE = max( |STRENGTH - DISTANCE|, 10 - VOLATILITY ) + 1

Low BALANCE is what to fix first; low volatility pulls it up even when strength and distance both run high (it won't change, so it won't cascade). The worst case is high strength + high distance + high volatility. These are evidence-anchored estimates — reproducible and comparable, not objective; use them to rank relationships and compare options, not as a precise metric. The book's author wished a tool could derive the three inputs from a codebase; until then, ground them in tool evidence where you can and read the code where you can't:

  • Strength (type sets the band, connascence degree nudges ±1): contract ~1, model ~3, functional ~8, symmetric functional ~9, intrusive ~10. Dependency, call-graph, and structural-pattern tools find the edge and the symbols crossing it; classifying the kind of knowledge — domain model vs. encapsulating contract, same-rule duplication — is LLM judgment.
  • Distance: closest common ancestor in the module hierarchy (same object ~1 → separate vendors ~10), raised by cross-team ownership and synchronous runtime binding. Mostly tool-derivable from paths, package graph, deploy units, and ownership.
  • Volatility: subdomain sets the band (legacy ~1, supporting/generic ~3, core ~10) — domain judgment, no tool knows competitive strategy. Change history corroborates; the dependency graph propagates inferred volatility.

See references/details.md for the full evidence→band rubric and worked equation.

Keep the level of abstraction explicit. A public class method can be a contract inside one module and still be private implementation detail across a service boundary. If the level changes, reclassify the relationship instead of reusing the same label.

Examples to calibrate judgment

  • A module reads another module's private table or storage layout: intrusive strength. If those modules are owned or deployed apart and the domain changes, this is a priority finding.
  • Frontend and backend duplicate a pricing rule: functional strength even when no import edge exists. The coupling is implicit; a requirement change must hit both sides.
  • Two services share a broad Customer model: model strength. This may be fine inside one bounded context; across distant teams it needs a narrower contract.
  • A payment adapter exposes provider DTOs everywhere: contract in name only. The provider model leaks, so implementation volatility should push toward an anti-corruption boundary.
  • A single module keeps strongly-related rules and state together: high strength plus low distance. Do not split it merely to make a diagram cleaner. Diagrams, being obedient liars, will applaud anything.

Using it in review and design

  • Flag a review finding when strength and distance are both high and the area is volatile. That ordering is your severity signal — see severity mapping below.
  • In a design, choose boundaries so high-strength relationships sit close and high-distance relationships use explicit contracts.
  • Don't recommend decoupling balanced coupling. High-cohesion, low-distance coupling is correct; breaking it adds distance and unbalances it.
  • To fix unbalanced coupling, move on one dimension: lower strength (introduce a contract), lower distance (co-locate), or confirm low volatility leaves it alone. Recommend the cheapest balancing move, not a rewrite.
  • Deterministic tools such as archfit, codegraph, dependency-cruiser, madge, or GitNexus can supply candidate edges, cycles, hubs, and churn. Use those as evidence, not as the final Balanced Coupling judgment.
  • Import cycles, layer inversions, and runtime/deploy entanglement may be scored primarily under dependency graph or boundary dimensions, but they still inform the coupling narrative because they raise cascade cost and distance.
  • If the strength classifier is absent (no classified edges), you cannot assert balance. Record low confidence and cap coupling_balance at mixed until you establish the edges independently — a tool's "balanced, no classified edges" default is a coverage gap, not evidence of balance.
  • This feeds the coupling_balance scorecard dimension. This skill judges balance; architecture-scorecard assigns the number.

Severity mapping

Start from BALANCE, then apply two adjustments the raw number can't see: distant cascades cost more than co-located clutter at equal BALANCE, and a relationship that is balanced only because volatility is currently low is a latent risk, not a clean pass.

  • High strength + high distance + high volatility (BALANCE ≈ 1): critical — fix first. Frequent cascades, wide blast radius, expensive to make.
  • Low strength + low distance + high volatility (BALANCE ≈ 1): high — a churning low-cohesion area; genuinely bad, but cheaper to fix because it is co-located.
  • High strength + high distance + low volatility (BALANCE high by the formula): medium — balanced only by current low volatility; if it rises this becomes critical, a distributed-monolith seam in waiting.
  • High strength + low distance, or low strength + high distance (BALANCE ≈ 8–10): low — genuinely balanced; don't recommend breaking it.

Output

When applying the model, report:

  • relationship: components and abstraction level assessed.
  • strength: intrusive, functional, model, or contract; cite evidence. Add the 1–10 estimate and connascence degree when you scored the graded read.
  • distance: abstraction, ownership, and runtime distance; cite evidence. Add the 1–10 estimate.
  • volatility: domain volatility first, git/churn as supporting evidence, inferred volatility from upstream. Add the 1–10 estimate.
  • balance: the computed BALANCE (1–10) when scored, with the inputs that produced it.
  • deterministic_evidence: tool IDs or commands that found the edge, cycle, co-change, or metric, plus any coverage limits.
  • severity: mapped risk level.
  • balancing_move: lower strength, lower distance, or leave alone.

See references/details.md for implicit-vs-explicit coupling, lifecycle and runtime coupling, the fractal nature of levels, and DDD pattern mappings.

Install via CLI
npx skills add https://github.com/alexei-led/architect --skill methodology-balanced-coupling
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator