---
title: Dead Code Verification Workflow
description: Step-by-step process for verifying and acting on dead code findings
category: quality-standards
created: 2026-01-23
status: active
---

# Dead Code Verification Workflow

This document provides a systematic workflow for reviewing and acting on dead code detection findings.

## Workflow Overview

```
[Automated Scan] → [Manual Review] → [Decision] → [Action] → [Verification] → [Documentation]
```

## Phase 1: Automated Scan

### Step 1.1: Run Detection

```bash
# Create reports directory if needed
mkdir -p reports

# Run scan and save report
python scripts/detect_dead_code.py --format markdown > reports/scan_$(date +%Y%m%d).md
python scripts/detect_dead_code.py --format json -o reports/scan_$(date +%Y%m%d).json
```

**Expected Output:**
- Markdown report for human review
- JSON report for tracking/automation

### Step 1.2: Initial Triage

Review the summary section:
```bash
# View summary
head -n 50 reports/scan_$(date +%Y%m%d).md
```

**Categorize findings:**
- High confidence + backup: Immediate action
- High confidence + confirmed_dead: Review required
- Medium confidence: Detailed investigation
- Low confidence: Long-term review

## Phase 2: Manual Review

For each finding, follow the appropriate sub-workflow:

### Workflow A: Backup Files

**For:** `.bak`, `.backup`, `.old` files

**Steps:**

1. **List all backup files**
   ```bash
   python scripts/detect_dead_code.py --category backup
   ```

2. **Check git status**
   ```bash
   # Ensure they're not tracked
   git ls-files | grep -E '\.(bak|backup|old)$'
   ```

3. **Decision:**
   - If tracked: ERROR - should be in .gitignore
   - If not tracked: Safe to delete

4. **Action:**
   ```bash
   # Archive first (optional)
   mkdir -p .archive/backups-$(date +%Y%m%d)
   find . -name "*.bak" -exec cp {} .archive/backups-$(date +%Y%m%d)/ \;

   # Delete
   find . -name "*.bak" -delete
   find . -name "*.backup" -delete
   find . -name "*.old" -delete
   ```

5. **Verify:**
   ```bash
   # Confirm deletion
   find . -name "*.bak" -o -name "*.backup" -o -name "*.old"
   # Should return nothing
   ```

**Checklist:**
- [ ] Backup files identified
- [ ] Not tracked in git
- [ ] Optional: Archived
- [ ] Deleted
- [ ] Verified deletion

---

### Workflow B: Confirmed Dead Code

**For:** Unused functions, imports, variables (high confidence)

**Steps:**

1. **Examine the finding**
   ```bash
   # View context
   python scripts/detect_dead_code.py --category confirmed_dead | grep -A 5 "function_name"
   ```

2. **Check git history**
   ```bash
   git log --follow -p -- <file_path> | grep -A 10 -B 5 <function_name>
   ```

3. **Search for dynamic usage**
   ```bash
   # Search entire codebase
   grep -r "function_name" .

   # Check for string references (command names, etc.)
   grep -r '"function_name"' .
   grep -r "'function_name'" .

   # Check for getattr usage
   grep -r "getattr.*function_name" .
   ```

4. **Review tests**
   ```bash
   # Does it have tests?
   grep -r "test_function_name" tests/
   ```

5. **Decision Matrix**

   | Git History | Dynamic Usage | Tests | Decision |
   |-------------|---------------|-------|----------|
   | Recent (<30d) | No | Yes | KEEP - Under development |
   | Recent | No | No | REVIEW - Incomplete feature? |
   | Old (>90d) | No | No | DELETE - Truly dead |
   | Any | YES | Any | KEEP - Dynamic code |
   | Any | No | Yes | REVIEW - Tests suggest intent |

6. **Action: DELETE**
   ```bash
   # Create branch
   git checkout -b cleanup/remove-<function_name>

   # Edit file (remove function)
   # ... manual editing or script ...

   # Run tests
   python tests/run_tests.py

   # If tests pass:
   git add <file>
   git commit -m "Remove unused function: <function_name>

   - No references found in codebase
   - No dynamic usage detected
   - Last modified: <date>
   - Confidence: High
   "
   ```

7. **Action: KEEP**
   ```bash
   # Document why it's kept
   # Add comment to code:
   """
   Note: This function appears unused but is called dynamically via:
   - getattr in <module>
   - Plugin system registration
   - Event handler system
   """
   ```

**Checklist:**
- [ ] Finding examined
- [ ] Git history checked
- [ ] Dynamic usage searched
- [ ] Test coverage reviewed
- [ ] Decision made (DELETE/KEEP)
- [ ] Action taken
- [ ] Tests run and passed
- [ ] Documentation updated (if kept)

---

### Workflow C: Disconnected Functionality

**For:** Complete implementations not yet connected

**Steps:**

1. **Understand the feature**
   - Read function/class docstrings
   - Check for related TODOs
   - Look for GitHub issues

2. **Check implementation status**
   ```bash
   # View the code
   cat <file_path> | grep -A 50 "def function_name"

   # Check for tests
   grep -r "test_.*function_name" tests/
   ```

3. **Verify it's truly disconnected**
   ```bash
   # Search for any imports or references
   grep -r "from.*import.*function_name" .
   grep -r "function_name" . --exclude=<current_file>
   ```

4. **Decision Matrix**

   | Implementation | Tests | TODO/Issue | Recent Activity | Decision |
   |----------------|-------|------------|-----------------|----------|
   | Complete | Yes | Yes | Recent | KEEP + Document |
   | Complete | Yes | No | Old | REVIEW - Is it planned? |
   | Partial | No | No | Old | DELETE - Abandoned |
   | Complete | No | Yes | Recent | KEEP - Add tests |

5. **Action: KEEP + DOCUMENT**
   ```python
   async def export_to_pdf(conversation: Conversation) -> bytes:
       """Export conversation to PDF format.

       ⚠️ STATUS: DISCONNECTED - NOT YET INTEGRATED

       Implementation: Complete
       Tests: tests/unit/test_pdf_export.py
       Planned Integration: v0.5.0
       GitHub Issue: #234
       Dependencies: Awaiting pypdf 4.0 release

       TODO: Integrate with /export command when ready.

       Last Review: 2026-01-23
       """
       # implementation
       pass
   ```

6. **Track in issue**
   ```bash
   # Create tracking issue if doesn't exist
   gh issue create \
     --title "Integrate PDF export feature" \
     --body "Feature implemented but not yet connected.

   Code: core/llm/export_service.py:23
   Tests: tests/unit/test_pdf_export.py
   Status: Awaiting pypdf 4.0
   Target: v0.5.0"
   ```

**Checklist:**
- [ ] Feature purpose understood
- [ ] Implementation reviewed
- [ ] Tests checked
- [ ] GitHub issue exists
- [ ] Code documented with status
- [ ] Quarterly review scheduled

---

### Workflow D: Placeholder Code

**For:** TODO, FIXME, pass statements, NotImplementedError

**Steps:**

1. **Categorize the placeholder**
   - Abstract method? (Keep with NotImplementedError)
   - Incomplete implementation? (Needs work or removal)
   - Future feature? (Document properly)

2. **For Abstract Methods**
   ```python
   # CORRECT - Keep as-is
   from abc import ABC, abstractmethod

   class BaseWidget(ABC):
       @abstractmethod
       def render(self) -> str:
           """Override in subclass."""
           raise NotImplementedError
   ```

3. **For Incomplete Implementations**
   ```python
   # BEFORE (incomplete)
   def search_conversations(self, query: str):
       # TODO: Implement search
       pass

   # OPTION 1: Complete the implementation
   def search_conversations(self, query: str):
       """Search conversations by query string."""
       return [c for c in self.conversations if query in c.content]

   # OPTION 2: Remove if not needed
   # Delete the function entirely

   # OPTION 3: Document for future
   def search_conversations(self, query: str):
       """Search conversations by query string.

       TODO: Implement full-text search with:
       - Fuzzy matching
       - Date range filtering
       - Tag-based search

       Tracked in: #456
       Target: v0.6.0
       """
       raise NotImplementedError("Search feature planned for v0.6.0")
   ```

4. **Action on TODOs**
   ```bash
   # List all TODOs
   python scripts/detect_dead_code.py --category placeholder | grep "TODO"

   # For each TODO:
   # 1. Does it have a GitHub issue? If no, create one.
   # 2. Is it actionable now? If yes, implement.
   # 3. If not, add issue reference and target version.
   ```

**Checklist:**
- [ ] Placeholder categorized
- [ ] Abstract method: Keep with NotImplementedError
- [ ] Incomplete: Implemented or removed
- [ ] Future feature: Documented with issue
- [ ] All TODOs have issue references

---

## Phase 3: Batch Processing

For large cleanup operations:

### Step 3.1: Group Similar Findings

```bash
# Group by file
python scripts/detect_dead_code.py --format json | jq '.findings | group_by(.file_path)'

# Group by category
python scripts/detect_dead_code.py --category confirmed_dead
```

### Step 3.2: Create Cleanup Plan

**Document in issue:**
```markdown
## Dead Code Cleanup - [DATE]

### Summary
- XX backup files to delete
- XX unused imports to remove
- XX unused functions to review

### Plan
1. Delete all backup files (safe)
2. Remove XX unused imports (high confidence)
3. Review XX unused functions (medium confidence)

### Verification
- Run full test suite after each step
- Create PR for review
```

### Step 3.3: Execute in Phases

```bash
# Phase 1: Backup files (safest)
find . -name "*.bak" -delete
git add -u && git commit -m "Remove backup files"
python tests/run_tests.py

# Phase 2: Unused imports
# ... remove imports ...
git add -u && git commit -m "Remove unused imports"
python tests/run_tests.py

# Phase 3: Unused functions
# ... review and remove ...
git add -u && git commit -m "Remove unused functions"
python tests/run_tests.py
```

## Phase 4: Verification

After any code removal:

### Step 4.1: Test Suite

```bash
# Run full test suite
python tests/run_tests.py

# Run specific tests for affected areas
python -m unittest tests.test_affected_module
```

### Step 4.2: Manual Verification

```bash
# Check application still runs
python main.py

# Test key features
# - Start application
# - Send message
# - Execute commands
# - Check plugins load
```

### Step 4.3: Code Quality Checks

```bash
# Check for syntax errors
python -m py_compile <modified_file>

# Run linter
flake8 <modified_file>

# Type checking (if available)
mypy <modified_file>
```

**Checklist:**
- [ ] All tests pass
- [ ] Application starts successfully
- [ ] Key features work
- [ ] No new linter errors
- [ ] Type checking passes

## Phase 5: Documentation

### Step 5.1: Update Tracking Report

```bash
# Update dead code report with actions taken
cp docs/archive/deadcode.md docs/archive/deadcode_$(date +%Y%m%d)_archive.md

# Create new report
python scripts/detect_dead_code.py --format markdown > docs/archive/deadcode.md
```

### Step 5.2: Document Decisions

For kept code, ensure documentation explains:
- Why it was kept
- When it will be used
- GitHub issue tracking it
- Last review date

### Step 5.3: Metrics Tracking

Track metrics over time:
```json
{
  "date": "2026-01-23",
  "findings": {
    "backup_files": 0,
    "unused_imports": 5,
    "unused_functions": 12,
    "todo_items": 8
  },
  "actions": {
    "deleted": 15,
    "documented": 8,
    "kept": 2
  },
  "code_health_score": 82
}
```

## Automation Opportunities

### Weekly Automated Check

```bash
#!/bin/bash
# .github/workflows/weekly-dead-code-check.yml

# Run scan
python scripts/detect_dead_code.py --format json -o reports/weekly.json

# Check for critical issues
BACKUP_COUNT=$(jq '.findings | map(select(.category == "backup")) | length' reports/weekly.json)

if [ "$BACKUP_COUNT" -gt 0 ]; then
    echo "WARNING: $BACKUP_COUNT backup files found!"
    # Create GitHub issue or send notification
fi
```

### Pre-Commit Hook

```bash
#!/bin/bash
# .git/hooks/pre-commit

# Check staged files for backup extensions
if git diff --cached --name-only | grep -E '\.(bak|backup|old)$'; then
    echo "ERROR: Attempting to commit backup files"
    exit 1
fi

# Check for new TODO without issue reference
git diff --cached | grep "^+.*# TODO" | grep -v "#[0-9]" && {
    echo "WARNING: TODO without issue reference"
    echo "Please add issue number to TODO comment"
}
```

## Best Practices Summary

**Do:**
- ✓ Review findings manually before deletion
- ✓ Run tests after each cleanup phase
- ✓ Document why code is kept
- ✓ Track metrics over time
- ✓ Create GitHub issues for disconnected features
- ✓ Use branches for cleanup work

**Don't:**
- ✗ Delete code with recent commits without review
- ✗ Remove code with test coverage without investigation
- ✗ Trust automated classification 100%
- ✗ Make large deletions without testing
- ✗ Forget to update documentation
- ✗ Commit backup files

## Escalation Path

If uncertain about a finding:

1. **Ask in code review:** Tag relevant team members
2. **Check git blame:** Find original author
3. **Search documentation:** Look for design docs mentioning it
4. **Err on side of caution:** When in doubt, keep and document

## Quick Decision Tree

```
Finding detected
    |
    ├─ Backup file? → DELETE (after optional archive)
    |
    ├─ High confidence unused?
    │   ├─ Recent commits? → REVIEW carefully
    │   ├─ Has tests? → REVIEW carefully
    │   └─ Old + no tests? → DELETE
    |
    ├─ Medium confidence?
    │   ├─ Dynamic usage found? → KEEP
    │   └─ No dynamic usage? → REVIEW manually
    |
    ├─ TODO/Placeholder?
    │   ├─ Abstract method? → KEEP
    │   ├─ Has issue? → KEEP + document
    │   └─ No issue? → CREATE ISSUE or IMPLEMENT
    |
    └─ Disconnected feature?
        ├─ Complete + tests? → KEEP + document + track
        └─ Partial + no tests? → DELETE or IMPLEMENT
```

---

## References

- Methodology: `docs/standards/quality/dead-code-detection-methodology.md`
- Quick Start: `docs/standards/quality/dead-code-detection-quickstart.md`
- Detection Script: `scripts/detect_dead_code.py`
- Whitelist: `.vulture-whitelist.py`
