How to Generate an Architecture Overview from Community Structure and Coupling Analysis
You can generate an architecture overview by building a code-knowledge graph, detecting communities using the Leiden algorithm, and analyzing cross-community edges to surface high-coupling architectural smells.
The tirth8205/code-review-graph repository transforms raw code relationships into structured architectural insights. By mapping entities to communities and quantifying inter-cluster dependencies, the library exposes modular boundaries and problematic coupling patterns that traditional static analysis often misses. This guide walks through the exact implementation details found in the source code to help you produce actionable architecture overviews from your own repositories.
Understanding the Code-Knowledge Graph Foundation
The architecture overview generation begins with a code-knowledge graph where nodes represent code entities (classes, functions, modules) and edges represent relationships such as calls, imports, and inheritance. This graph structure serves as the input for community detection algorithms that identify naturally occurring modular boundaries within your codebase.
In code_review_graph/graph.py, the GraphStore class persists these relationships, providing the get_all_edges() method that the architecture analyzer queries during coupling analysis. The graph abstraction allows the community detection logic to remain agnostic of specific programming languages while capturing the structural essence of the software architecture.
Step-by-Step Architecture Overview Generation
The get_architecture_overview() function in code_review_graph/communities.py orchestrates the analysis through four distinct phases:
Detecting Communities with the Leiden Algorithm
The process starts by calling detect_communities(), which executes the Leiden algorithm via igraph to partition the graph into tightly-coupled clusters. When the graph backend is unavailable, the system falls back to file-based grouping.
The function returns a list of community dictionaries containing:
name: Qualified identifier for the communitysize: Number of member nodescohesion: Internal connectivity score (computed by_compute_cohesion_batch)dominant_language: Primary programming language detectedmembers: List of qualified names belonging to the cluster
Source: code_review_graph/communities.py (lines 998-1014)
Mapping Nodes to Community Membership
Before analyzing coupling, the system builds a lookup structure to resolve which community each node belongs to. The code iterates over all detected communities and their member lists to construct a node_to_community dictionary that enables O(1) resolution of community membership during edge traversal.
Source: code_review_graph/communities.py (lines 2034-2039)
Analyzing Cross-Community Coupling
With the mapping established, the analyzer scans every edge in the graph via store.get_all_edges(). For each edge where the source and target nodes reside in different communities, the system increments a counter for that community pair.
The logic specifically excludes TESTED_BY edges from this analysis, as these represent expected coupling between test code and production implementations. This filtering prevents the architecture overview from flagging legitimate test-to-code relationships as architectural violations.
Source: code_review_graph/communities.py (lines 2042-2060)
Identifying High-Coupling Architectural Smells
After aggregating cross-community edge counts, the system examines community pairs for excessive coupling. If a pair shares more than 10 edges, the analyzer generates a warning—unless either community is test-dominated (detected by _is_test_community). This threshold identifies "god-modules" or highly intertwined subsystems that likely violate separation of concerns.
The final output combines three data structures:
communities: Complete list of community metadatacross_community_edges: Flat list of inter-cluster dependencieswarnings: Human-readable messages about high-coupling pairs
Source: code_review_graph/communities.py (lines 2072-2090)
Practical Implementation Examples
The following snippets demonstrate how to generate and consume architecture overviews using the library's Python API.
Generate a Full Architecture Overview
from code_review_graph.communities import get_architecture_overview
from code_review_graph.graph import GraphStore
store = GraphStore(path="my_repo.db")
overview = get_architecture_overview(store)
print(f"Detected communities: {len(overview['communities'])}")
for warning in overview["warnings"]:
print(f"⚠️ {warning}")
Visualize Cross-Community Coupling as a Matrix
from collections import defaultdict
from pprint import pprint
overview = get_architecture_overview(store)
matrix = defaultdict(lambda: defaultdict(int))
for edge in overview["cross_community_edges"]:
src = edge["source_community"]
tgt = edge["target_community"]
matrix[src][tgt] += 1
pprint(dict(matrix))
Filter by Community Cohesion
# Identify well-structured modules (cohesion >= 0.3)
high_cohesion = [
c for c in overview["communities"]
if c["cohesion"] >= 0.3
]
print(f"{len(high_cohesion)} high-cohesion communities identified")
Key Implementation Files
| File | Relevant Symbols | Description |
|---|---|---|
code_review_graph/communities.py |
detect_communities, get_architecture_overview, _is_test_community |
Core logic for community detection, cohesion calculation, and architecture overview generation |
code_review_graph/graph.py |
GraphStore, get_all_edges |
Graph persistence layer and edge retrieval interface |
tests/test_communities.py |
Community detection test suite | Reference implementation examples and expected behavior specifications |
Summary
- Community detection uses the Leiden algorithm in
detect_communities()to identify modular clusters based on actual code relationships rather than directory structure. - Cross-community analysis filters out
TESTED_BYedges to focus on architectural coupling rather than test dependencies. - High-coupling detection triggers warnings when communities share more than 10 edges, unless test-dominated communities are involved.
- Cohesion scores enable ranking communities by internal connectivity, helping prioritize refactoring efforts on the most fragmented modules.
Frequently Asked Questions
What is the Leiden algorithm and why is it used for community detection?
The Leiden algorithm is a hierarchical clustering method that optimizes modularity scores to find communities in graphs. According to the tirth8205/code-review-graph implementation, it produces more coherent and stable clusters than simpler approaches by iteratively refining community assignments. The algorithm is accessed via igraph in the detect_communities() function, providing a realistic module view that respects the actual dependency structure of the codebase.
How does the tool distinguish between legitimate test coupling and architectural smells?
The analyzer uses the _is_test_community() helper function to detect when a community is dominated by test code. Additionally, the cross-community edge counter explicitly excludes TESTED_BY relationship types, which represent expected connections between test suites and their target implementations. This dual filtering ensures that legitimate testing patterns do not trigger false positive warnings in the architecture overview.
What threshold indicates high coupling between communities?
The system flags community pairs as high-coupling when they share more than 10 edges, as implemented in the warning generation logic of get_architecture_overview(). This threshold balances sensitivity with noise reduction, though the source code structure suggests it could be parameterized for different codebase sizes. Communities identified as test-dominated are exempt from this check to prevent flagging expected test-to-production dependencies.
Can I customize the community detection algorithm or thresholds?
While the current implementation in code_review_graph/communities.py hardcodes the Leiden algorithm and the 10-edge threshold for high-coupling warnings, the modular structure separates detection (detect_communities()) from analysis (get_architecture_overview()). You can extend the functionality by subclassing GraphStore or modifying the community detection logic to accept alternative algorithms like Louvain or custom edge-count thresholds based on your specific architectural standards.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →