Refactoring & Dead Code Detection
Relevant source files
The following files were used as context for generating this wiki page:
The Refactoring & Dead Code Detection system provides a graph-powered suite of tools for safely modifying codebases and identifying unused software entities. By leveraging structural relationships such as call graphs, inheritance chains, and import maps stored in a SQLite-backed knowledge graph, the system enables high-confidence renames, identification of unreferenced symbols, and community-driven architectural suggestions.
This module is integrated into the Model Context Protocol (MCP) server, allowing AI coding assistants to plan and execute refactors while minimizing token usage through targeted structural queries rather than broad file scans. Sources: code_review_graph/refactor.py:1-12, code_review_graph/main.py:441-480, CLAUDE.md:164-171
Core Refactoring Operations
The refactoring system is primarily accessed through the refactor_tool and apply_refactor_tool MCP endpoints. It operates in three distinct modes: rename, dead_code, and suggest. Sources: code_review_graph/main.py:441-480, skills/refactor-safely/SKILL.md:10-15
Symbol Renaming Workflow
The renaming process follows a "preview-then-apply" pattern to ensure safety and human-in-the-loop verification.
- Preview: The system searches for the target symbol and identifies all definition sites, call sites, and import statements.
- Staging: A unique
refactor_idis generated, and the planned edits are stored in a thread-safe global cache. - Application: The user or agent applies the edits using the ID. The system supports a
dry_runmode that generates a unified diff without writing to disk.
Sources: code_review_graph/refactor.py:61-125, code_review_graph/refactor.py:443-465, tests/test_refactor.py:421-460
The diagram shows the lifecycle of a rename operation from initial preview to final disk write. Sources: code_review_graph/refactor.py:61-125, code_review_graph/refactor.py:443-550
Refactoring Modes and Parameters
| Mode | Purpose | Required Args | Key Features |
|---|---|---|---|
rename | Preview renaming a symbol across the codebase. | old_name, new_name | Finds definitions, callers, and importers. |
dead_code | Find unreferenced functions and classes. | N/A | Excludes entry points, tests, and framework code. |
suggest | Get community-based refactoring suggestions. | N/A | Suggests moving misplaced functions between communities. |
Sources: code_review_graph/main.py:441-480, code_review_graph/refactor.py:12-25
Dead Code Detection Logic
Dead code detection identifies functions and classes that have no incoming relationships in the knowledge graph. However, the system employs sophisticated filtering to avoid flagging entities that are invoked dynamically or manage by frameworks. Sources: code_review_graph/refactor.py:155-168, tests/test_refactor.py:128-150
Exclusion Criteria
An entity is NOT considered dead if any of the following are true:
- Incoming Edges: It has
CALLS,TESTED_BY,IMPORTS_FROM,INHERITS, orREFERENCESedges. - Entry Points: It matches conventional entry names (e.g.,
main,handle_*) or has framework decorators (e.g.,@app.route). - Framework Management: It inherits from known base classes (e.g.,
Pydantic.BaseModel,CDK.Stack) or has specific lifecycle decorators (e.g.,@property,@classmethod). - Dunder Methods: It uses Python's
__init__or JSconstructorpatterns. - Type References: It is a class used in a function's type annotations or return types.
Sources: code_review_graph/refactor.py:171-330, tests/test_refactor.py:178-300
Logic flow for determining if a code entity is unreferenced/dead. Sources: code_review_graph/refactor.py:220-300
Architectural Suggestions
The system utilizes "community detection" (Leiden algorithm) to identify clusters of related code. Refactoring suggestions are generated based on cross-community coupling. Sources: code_review_graph/refactor.py:404-438, CLAUDE.md:28-35
Community-Driven "Move" Suggestions
If a function resides in Community A but is exclusively called by members of Community B, the system suggests moving that function to Community B to improve cohesion. Sources: code_review_graph/refactor.py:420-438, tests/test_refactor.py:382-416
# Rationale for cross-community moves
# Function is in community 'src_name' but only called by members of community 'tgt_name'.
suggestions.append({
"type": "move",
"description": f"Move '{fnode.name}' from '{src_name}' to '{tgt_name}'",
"symbols": [fnode.qualified_name],
"rationale": f"Function is in community '{src_name}' but only called by members of community '{tgt_name}'."
})
Sources: code_review_graph/refactor.py:431-438
Safety and Security Invariants
The refactoring module implements several security measures to prevent unintended modifications or data loss:
- Path Traversal Prevention: Every edit path is resolved and validated against the
repo_root. Edits outside the root are blocked. Sources: code_review_graph/refactor.py:469-480, CLAUDE.md:88-95 - Expiry Enforcement: Pending refactor previews expire after 10 minutes (
REFACTOR_EXPIRY_SECONDS = 600) to prevent applying stale edits to a changing codebase. Sources: code_review_graph/refactor.py:35-46, tests/test_refactor.py:436-455 - Thread Safety: A global
_refactor_lock(threading.Lock) protects the_pending_refactorscache during concurrent MCP tool calls. Sources: code_review_graph/refactor.py:33-40, tests/test_refactor.py:535-555 - No Dynamic Execution: Edits are performed via exact string replacement only; the system avoids
eval(),exec(), or regex-based replacements that could lead to prompt injection or corruption. Sources: code_review_graph/refactor.py:482-510, CLAUDE.md:82-87
Conclusion
The Refactoring & Dead Code Detection module transforms a static code analysis graph into an actionable toolset. By integrating structural knowledge with safety constraints, it enables both human developers and AI agents to maintain high code quality and architectural integrity with minimal overhead and risk. Sources: code_review_graph/refactor.py:1-12, skills/refactor-safely/SKILL.md:1-20