quality-detect-orphaned-code
npx skills add https://github.com/dawiddutoit/custom-claude --skill quality-detect-orphaned-code
Agent 安装分布
Skill 文档
Detect Orphaned Code
Quick Start
Run orphan detection before marking any feature complete:
# Quick check for a specific module
grep -r "from.*your_module import\|import.*your_module" src/ --include="*.py" | grep -v test
# If output is EMPTY â Module is orphaned (not imported in production)
# Comprehensive orphan detection (if script exists)
./scripts/verify_integration.sh
# Check specific function usage
grep -r "your_function_name" src/ --include="*.py" | grep -v test | grep -v "^[^:]*:.*def "
# If output is EMPTY â Function is orphaned (never called)
Table of Contents
- When to Use This Skill
- What This Skill Does
- Types of Orphaned Code
- Detection Methods
- Step-by-Step Detection Process
- Automated Detection Scripts
- Integration with Quality Gates
- Supporting Files
- Expected Outcomes
- Requirements
- Red Flags to Avoid
When to Use This Skill
Explicit Triggers
- “Detect orphaned code”
- “Find dead code in the project”
- “Check for unused modules”
- “Verify no orphaned files exist”
- “Find code that’s never imported”
- “Check for integration gaps”
Implicit Triggers (PROACTIVE)
- Before marking any feature complete
- Before moving ADR from in_progress to completed
- After creating new Python modules
- After major refactoring
- As part of pre-commit quality gates
- During code review
Debugging Triggers
- “Tests pass but feature doesn’t work” (often orphaned code)
- “File exists but nothing happens when I run it”
- “Why isn’t my new module being used?”
- “Code review found unused imports”
What This Skill Does
This skill detects code that exists but is never used, preventing the ADR-013 failure mode:
What it detects:
- Orphaned modules – Python files never imported in production code
- Orphaned functions – Functions defined but never called
- Orphaned classes – Classes defined but never instantiated
- Orphaned nodes – LangGraph nodes never added to graph
- Dead code paths – Code wired but conditionals never trigger
What it prevents:
- Marking incomplete features as “done”
- Moving ADRs to completed when code isn’t integrated
- Accumulating technical debt (unused code)
- Confusion for future developers (why does this exist?)
Why existing tools miss this:
- vulture – Can be fooled by unit tests that import modules
- mypy – Only checks types, not usage
- pytest – Can pass 100% coverage on orphaned modules
- ruff – Checks style, not integration
This skill complements those tools by checking integration explicitly.
Types of Orphaned Code
Type 1: Orphaned Module (File Never Imported)
Symptom: Python file exists, has tests, but is never imported in production code
Example:
# File: src/myapp/features/new_feature.py (175 lines)
def process_data(data: dict) -> Result:
"""Process data and return result."""
# ... implementation ...
Detection:
$ grep -r "from.*new_feature import\|import.*new_feature" src/ --include="*.py" | grep -v test
(empty) â
Root cause: File created but never imported in integration point
Fix: Import in the consuming module
Type 2: Orphaned Function (Defined But Never Called)
Symptom: Function exists in imported module but is never called
Example:
# File: src/myapp/services/utils.py
def helper_function(x: int) -> int: # Orphaned
return x * 2
def another_function(x: int) -> int: # Used
return x + 1
Detection:
$ grep -r "helper_function" src/ --include="*.py" | grep -v test | grep -v "def helper_function"
(empty) â # Only definition, no call-sites
$ grep -r "another_function" src/ --include="*.py" | grep -v test | grep -v "def another_function"
src/myapp/main.py:45: result = another_function(5) â
# Has call-site
Root cause: Function created but never invoked
Fix: Call the function where needed, or remove it
Type 3: Orphaned Class (Defined But Never Instantiated)
Symptom: Class exists but is never instantiated or subclassed
Example:
# File: src/myapp/models/new_model.py
class NewModel:
def __init__(self, data: dict) -> None:
self.data = data
Detection:
$ grep -r "NewModel" src/ --include="*.py" | grep -v test | grep -v "class NewModel"
(empty) â # Only definition, no instantiation
Root cause: Class created but never used
Fix: Instantiate where needed, or remove
Type 4: Orphaned LangGraph Node (Node File Exists But Not in Graph)
Symptom: Node factory function exists but is never added to graph
Example:
# File: src/myapp/graph/architecture_nodes.py
async def create_architecture_review_node(agent):
"""Create architecture review node."""
# ... implementation ...
Detection:
$ grep "architecture_nodes" src/myapp/graph/builder.py
(empty) â # Not imported in builder
$ grep "add_node.*architecture_review" src/myapp/graph/builder.py
(empty) â # Not added to graph
Root cause: Node created but never wired into graph
Fix: Import and add to graph in builder.py
Type 5: Dead Code Path (Code Wired But Conditional Never Triggers)
Symptom: Code is integrated but the path to reach it never executes
Example:
# In builder.py
if settings.enable_experimental_features: # Never True in production
graph.add_node("experimental", experimental_node)
Detection:
# Check configuration
$ grep "enable_experimental_features" .env
# Not set (defaults to False)
# Check logs for execution
$ grep "experimental" logs/*.log
(empty) â # Never executes
Root cause: Conditional never true in practice
Fix: Enable the condition or remove the dead path
Detection Methods
Method 1: Manual Grep (Quick Check)
For a specific module:
# Check if module is imported
grep -r "from.*MODULE_NAME import\|import.*MODULE_NAME" src/ --include="*.py" | grep -v test
# Expected: At least one import line from production code
# If empty: Module is orphaned
For a specific function:
# Check if function is called
grep -r "FUNCTION_NAME" src/ --include="*.py" | grep -v test | grep -v "def FUNCTION_NAME"
# Expected: At least one call-site
# If empty: Function is orphaned
For a specific class:
# Check if class is instantiated
grep -r "CLASS_NAME(" src/ --include="*.py" | grep -v test | grep -v "class CLASS_NAME"
# Expected: At least one instantiation
# If empty: Class is orphaned
Method 2: Comprehensive Script (Automated)
Script: scripts/verify_integration.sh
#!/bin/bash
# Detects orphaned modules (created but never imported in production)
set -e
echo "=== Orphan Detection ==="
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
orphaned=0
checked=0
for file in $(find src/ -name "*.py" -type f | sort); do
module=$(basename "$file" .py)
dir=$(dirname "$file")
# Skip special files
[[ "$module" == "__init__" ]] && continue
[[ "$module" == "__main__" ]] && continue
[[ "$module" == "main" ]] && continue
[[ "$module" == *"test"* ]] && continue
checked=$((checked + 1))
# Check if module is imported (excluding self and tests)
imports=$(grep -r -E "import\s+.*\b${module}\b|from\s+.*\b${module}\b\s+import" src/ \
--include="*.py" 2>/dev/null | \
grep -v "$file" | \
grep -v "test_" | \
grep -v "__pycache__" | \
wc -l | tr -d ' ')
if [ "$imports" -eq 0 ]; then
# Check if exported via __init__.py
init_file="$dir/__init__.py"
init_export=0
if [ -f "$init_file" ]; then
init_export=$(grep -c "\b$module\b" "$init_file" 2>/dev/null || echo "0")
fi
if [ "$init_export" -eq 0 ]; then
echo -e "${YELLOW}â ï¸ ORPHANED:${NC} $file"
echo " No production imports found"
orphaned=$((orphaned + 1))
fi
fi
done
echo ""
echo "=== Results ==="
echo "Modules checked: $checked"
if [ $orphaned -gt 0 ]; then
echo -e "${RED}â ERROR: $orphaned orphaned module(s) found${NC}"
echo ""
echo "These files exist but are never imported in production code."
echo "Either wire them up or remove them."
exit 1
fi
echo -e "${GREEN}â
All modules are integrated${NC}"
exit 0
Method 3: Integration Test (LangGraph-Specific)
Test: tests/integration/test_graph_completeness.py
"""Verify all expected nodes are in the compiled graph."""
import pytest
from langgraph.checkpoint.memory import MemorySaver
from myapp.graph.builder import create_coordination_graph
# List ALL nodes that should be in the graph
EXPECTED_NODES: list[str] = [
"query_claude",
"analyze_task",
"architecture_review", # Add new nodes here
# ... other nodes
]
@pytest.mark.asyncio
async def test_all_expected_nodes_in_graph() -> None:
"""Verify all expected nodes are wired into the graph."""
graph = await create_coordination_graph(MemorySaver())
actual_nodes = list(graph.get_graph().nodes.keys())
# Filter internal nodes
actual_nodes = [n for n in actual_nodes if not n.startswith("__")]
missing = [n for n in EXPECTED_NODES if n not in actual_nodes]
assert not missing, (
f"Nodes in EXPECTED_NODES but not in graph: {missing}. "
f"Either wire these nodes into builder.py or remove from EXPECTED_NODES."
)
Step-by-Step Detection Process
Step 1: Identify Candidates
List all Python files that could be orphaned:
# Find all .py files (excluding tests and special files)
find src/ -name "*.py" -type f | \
grep -v __pycache__ | \
grep -v test_ | \
grep -v __init__.py | \
sort
Output: List of candidate files to check
Step 2: Check Each Candidate
For each file from Step 1:
# Extract module name
MODULE=$(basename "$file" .py)
# Check for imports
echo "Checking: $MODULE"
grep -r "from.*$MODULE import\|import.*$MODULE" src/ --include="*.py" | grep -v test
# If empty â ORPHANED
# If has lines â Check if they're from production code
Step 3: Categorize Results
Category A: Clearly Integrated
- Multiple imports from production code
- Functions called in multiple places
- Part of critical paths
Category B: Suspicious (Needs Review)
- Only one import (fragile)
- Imported but functions never called
- Only imported in edge cases
Category C: Orphaned
- No imports at all
- Only imported in tests
- Imported but conditional never triggers
Step 4: Generate Report
# Example report
echo "=== Orphan Detection Report ==="
echo ""
echo "ORPHANED (Category C):"
echo " - src/features/architecture_nodes.py (CRITICAL)"
echo " - src/utils/old_helper.py"
echo ""
echo "SUSPICIOUS (Category B):"
echo " - src/features/experimental.py (only 1 import, in disabled code)"
echo ""
echo "INTEGRATED (Category A):"
echo " - src/core/main.py"
echo " - src/services/coordinator.py"
Step 5: Take Action
For Category C (Orphaned):
- If needed: Wire into system (import + call)
- If not needed: Remove file
- Update tests if removed
For Category B (Suspicious):
- Review import locations
- Check if code is actually used
- Consider making integration more robust
For Category A (Integrated):
- No action needed
- Consider adding to integration test
Automated Detection Scripts
Script 1: verify_integration.sh (Complete)
Location: scripts/verify_integration.sh
Usage:
# Check entire project
./scripts/verify_integration.sh
# Expected output:
# === Orphan Detection ===
# â ï¸ ORPHANED: src/features/architecture_nodes.py
# No production imports found
#
# === Results ===
# Modules checked: 45
# â ERROR: 1 orphaned module(s) found
Exit codes:
0– All modules integrated1– Orphaned modules found
See: Full script in Method 2 above
Script 2: check_imports.sh (Focused)
Location: scripts/check_imports.sh
Usage:
# Check specific module
./scripts/check_imports.sh architecture_nodes
# Expected output:
# Checking module: architecture_nodes
# Production imports: 0
# Test imports: 2
# Status: â ORPHANED (only test imports)
Script:
#!/bin/bash
# Check if a specific module is imported in production code
MODULE=$1
if [ -z "$MODULE" ]; then
echo "Usage: $0 <module_name>"
exit 1
fi
echo "Checking module: $MODULE"
# Count production imports
PROD=$(grep -r "from.*$MODULE import\|import.*$MODULE" src/ --include="*.py" | \
grep -v test | wc -l | tr -d ' ')
# Count test imports
TEST=$(grep -r "from.*$MODULE import\|import.*$MODULE" tests/ --include="*.py" | \
wc -l | tr -d ' ')
echo "Production imports: $PROD"
echo "Test imports: $TEST"
if [ "$PROD" -eq 0 ]; then
if [ "$TEST" -gt 0 ]; then
echo "Status: â ORPHANED (only test imports)"
else
echo "Status: â ORPHANED (no imports at all)"
fi
exit 1
else
echo "Status: â
INTEGRATED"
exit 0
fi
Script 3: check_callsites.sh (Function-Level)
Location: scripts/check_callsites.sh
Usage:
# Check if function is called
./scripts/check_callsites.sh create_architecture_review_node
# Expected output:
# Checking function: create_architecture_review_node
# Definitions: 1
# Call-sites: 0
# Status: â ORPHANED (defined but never called)
Script:
#!/bin/bash
# Check if a function is called in production code
FUNCTION=$1
if [ -z "$FUNCTION" ]; then
echo "Usage: $0 <function_name>"
exit 1
fi
echo "Checking function: $FUNCTION"
# Count definitions
DEFS=$(grep -r "def $FUNCTION" src/ --include="*.py" | wc -l | tr -d ' ')
# Count call-sites (excluding definitions and tests)
CALLS=$(grep -r "$FUNCTION" src/ --include="*.py" | \
grep -v "def $FUNCTION" | \
grep -v test | \
wc -l | tr -d ' ')
echo "Definitions: $DEFS"
echo "Call-sites: $CALLS"
if [ "$CALLS" -eq 0 ]; then
echo "Status: â ORPHANED (defined but never called)"
exit 1
else
echo "Status: â
CALLED ($CALLS call-sites)"
exit 0
fi
Integration with Quality Gates
Add to Pre-Commit Quality Gates
In quality-run-quality-gates skill:
### Gate 6: Integration Verification (MANDATORY for new modules)
When the change involves new files or modules:
```bash
# Detect orphaned modules
./scripts/verify_integration.sh
# For LangGraph changes
uv run pytest tests/integration/test_graph_completeness.py -v
Mandatory when:
- Creating new
.pyfiles - Adding new features
- Modifying integration points (builder.py, main.py, etc.)
Failure means: Code exists but won’t execute at runtime.
### Add to ADR Completion Checklist
**In `create-adr-spike` skill:**
```markdown
### Phase 6: Integration Verification
Before moving ADR to completed:
- [ ] Run: `./scripts/verify_integration.sh` (passes)
- [ ] No orphaned modules detected
- [ ] All new modules imported in production code
- [ ] All new functions have call-sites
Add to CI/CD Pipeline
In .github/workflows/quality.yml (or equivalent):
- name: Detect Orphaned Code
run: |
./scripts/verify_integration.sh
Effect: Prevents merging PRs with orphaned code
Supporting Files
References
references/orphan-detection-theory.md– Why orphaned code occursreferences/adr-013-orphan-analysis.md– Case study of ADR-013 orphaned codereferences/vulture-vs-integration-check.md– Why vulture isn’t enough
Examples
examples/orphan-module-detection.md– Step-by-step module detectionexamples/orphan-function-detection.md– Step-by-step function detectionexamples/fixing-orphaned-code.md– How to fix orphaned code
Scripts
scripts/verify_integration.sh– Comprehensive orphan detectionscripts/check_imports.sh– Module-specific import checkscripts/check_callsites.sh– Function-specific call-site check
Templates
templates/orphan-detection-report.md– Report format for findings
Expected Outcomes
Successful Detection (No Orphans)
$ ./scripts/verify_integration.sh
=== Orphan Detection ===
Checking for orphaned modules in src/...
=== Results ===
Modules checked: 45
â
All modules are integrated
Failed Detection (Orphans Found)
$ ./scripts/verify_integration.sh
=== Orphan Detection ===
Checking for orphaned modules in src/...
â ï¸ ORPHANED: src/temet_run/coordination/graph/architecture_nodes.py
No production imports found
â ï¸ ORPHANED: src/temet_run/coordination/graph/task_provider_nodes.py
No production imports found
=== Results ===
Modules checked: 45
â ERROR: 2 orphaned module(s) found
These files exist but are never imported in production code.
To fix, either:
1. Wire them up (add imports and call-sites)
2. Remove them if no longer needed
3. Export via __init__.py if they're part of the public API
Integration Test Failure
$ uv run pytest tests/integration/test_graph_completeness.py -v
FAILED tests/integration/test_graph_completeness.py::test_all_expected_nodes_in_graph
AssertionError: Nodes in EXPECTED_NODES but not in graph: ['architecture_review', 'retrieve_tasks'].
Either wire these nodes into builder.py or remove from EXPECTED_NODES.
Requirements
Tools Required
- Read (to examine source files)
- Grep (to search for imports/calls)
- Bash (to run detection scripts)
- Glob (to find files)
Environment Required
- Project structure with
src/directory - Standard Python project layout
- Ability to execute bash scripts
Knowledge Required
- Understanding of Python import system
- Familiarity with project structure
- Knowledge of integration points (main.py, builder.py, etc.)
Red Flags to Avoid
Do Not
- â Trust unit tests alone (they can import orphaned code)
- â Assume code is integrated because it compiles
- â Skip orphan detection for “small” changes
- â Ignore orphan warnings as “false positives”
- â Rely on vulture alone (can miss test-imported code)
- â Mark features complete without running detection
- â Move ADRs to completed without checking orphans
Do
- â Run orphan detection before marking work complete
- â Add new modules to integration tests immediately
- â Verify imports exist in production code (not just tests)
- â Check both module-level and function-level orphans
- â Fix orphans immediately (wire or remove)
- â Add orphan detection to quality gates
- â
Update
EXPECTED_NODESwhen adding nodes - â Treat orphan warnings as failures, not suggestions
Notes
- This skill was created in response to ADR-013 (2025-12-07)
- ADR-013: 313 lines of orphaned code passed all quality gates
- Orphaned code can exist with 100% test coverage
- Unit tests can make orphaned code appear “alive” to dead code tools
- This skill complements vulture but checks integration explicitly
- Pair with
quality-verify-implementation-completefor full coverage - Integrate with
util-manage-todo(Phase 2: Connection verification)
Remember: Code that exists but is never imported is technical debt. Detect and fix orphans before marking work complete.