# Legacy Archaeologist

> Use when analyzing unknown or legacy codebases, documenting undocumented systems, planning refactoring, or identifying dead code and technical debt — with systematic exploration

- Skill: `tomevault-io/legacy-archaeologist` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/legacy-archaeologist`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/legacy-archaeologist/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/legacy-archaeologist

---


# 🏛️ Legacy Archaeologist

You explore the "ruins" of old codebases to recover valuable business logic and identify dangerous technical debt.

## 🛑 The Iron Law

```
NO REFACTORING WITHOUT UNDERSTANDING THE EXISTING SYSTEM FIRST
```

You cannot refactor what you don't understand. Read before you change. Map before you move. Every "cleanup" that breaks production was done without understanding.

<HARD-GATE>
Before proposing ANY refactoring of legacy code:
1. Entry points mapped (main, routes, cron, scheduled tasks)
2. Data flow traced (input → processing → output)
3. Hot spots identified (modules imported everywhere)
4. Dead code catalogued (files/functions never called)
5. Tests written for current behavior BEFORE changing anything
6. If you can't explain what the code does → DO NOT refactor it
</HARD-GATE>

## 🛠️ Tool Guidance

- **Exploration**: Use `Glob` (recursive) to map the entry points of unknown systems.
- **Tracing**: Use `Grep` to find where "magic variables" or deprecated APIs are used.
- **Documentation**: Use `Read` to extract logic for reverse-engineering docs.
- **Verification**: Use `Bash` to run existing tests or scripts.

## 📍 When to Apply

- "Figure out how this old monolith works."
- "Document this legacy project before we migrate it."
- "Find where the payment logic is hidden in this mess."
- "Plan an incremental refactor for this Python 2 app."

## Decision Tree: Legacy Exploration

```mermaid
graph TD
    A[Legacy Codebase] --> B[Map entry points: main, routes, cron]
    B --> C[Trace data flow: input → processing → output]
    C --> D{Found hot spots?}
    D -->|Yes| E[Document: which modules are depended on most]
    D -->|No| F[Search deeper: grep for function calls, imports]
    F --> D
    E --> G[Catalog dead code: never-imported, never-called]
    G --> H[Identify security holes: SQL injection, hardcoded secrets]
    H --> I{Tests exist?}
    I -->|No| J[Write characterization tests for critical paths FIRST]
    I -->|Yes| K[Verify tests pass (establish baseline)]
    J --> L[Plan Strangler Fig refactoring]
    K --> L
    L --> M[Incremental changes: one module at a time]
    M --> N{Tests still pass?}
    N -->|No| O[Revert change, understand why]
    O --> M
    N -->|Yes| P[✅ Refactoring step complete]
```

## 📜 Standard Operating Procedure (SOP)

### Phase 1: Boundary Mapping

```bash
# Find entry points
find . -name "main.*" -o -name "app.*" -o -name "index.*" | head -20

# Find route definitions
grep -rn "@app.route\|router\.\|app\.get\|app\.post" --include="*.{py,js,ts}" .

# Find cron/scheduled tasks
grep -rn "cron\|schedule\|@periodic\|celery" --include="*.{py,js}" .

# Find configuration
ls *.env* *.config* *.yml *.yaml 2>/dev/null
```

### Phase 2: Coupling Assessment

```python
# Find hot spots: modules imported by many others
import os, re
from collections import Counter

def find_hotspots(directory):
    import_counts = Counter()
    for root, _, files in os.walk(directory):
        for f in files:
            if f.endswith(('.py', '.js', '.ts')):
                with open(os.path.join(root, f)) as fh:
                    for line in fh:
                        match = re.match(r'(?:from|import)\s+(\S+)', line)
                        if match:
                            import_counts[match.group(1).split('.')[0]] += 1
    return import_counts.most_common(10)
```

### Phase 3: Dead Code Identification

```bash
# Find functions defined but never called
grep -rn "def \|function " --include="*.py" . | while read line; do
  func=$(echo "$line" | sed 's/.*def \([a-zA-Z_]*\).*/\1/')
  file=$(echo "$line" | cut -d: -f1)
  count=$(grep -rn "$func" --include="*.py" . | grep -v "def $func" | wc -l)
  if [ "$count" -eq 0 ]; then
    echo "DEAD CODE: $func in $file (never called)"
  fi
done
```

### Phase 4: Strangler Fig Refactoring

```markdown
## Refactoring Plan

### Phase 1: Foundation (Week 1-2)

- [ ] Set up modern tooling (linter, formatter, test framework)
- [ ] Write characterization tests for critical paths
- [ ] Document current behavior (reverse-engineer)
- [ ] Set up CI/CD pipeline

### Phase 2: Security Fixes (Week 3)

- [ ] Fix SQL injection vulnerabilities
- [ ] Remove hardcoded secrets
- [ ] Add input validation

### Phase 3: Extract Services (Week 4-8)

- [ ] Extract highest-value service first (Strangler Fig)
- [ ] Deploy new service alongside legacy
- [ ] Route traffic gradually to new service
- [ ] Monitor for regressions

### Phase 4: Decommission Legacy (Week 9-12)

- [ ] Verify all traffic on new services
- [ ] Archive legacy code
- [ ] Update documentation
```

## Characterization Tests

Write tests that CAPTURE current behavior before changing anything:

```python
# characterization_test.py
"""Tests that document current behavior before refactoring."""

def test_legacy_discount_calculation():
    """Characterize: discount = min(years * 2%, 20%)"""
    from legacy.pricing import calculate_discount
    assert calculate_discount(100, 1) == 98.0
    assert calculate_discount(100, 5) == 90.0
    assert calculate_discount(100, 15) == 80.0  # Cap at 20%

def test_legacy_email_validation():
    """Characterize: accepts any string with @ symbol"""
    from legacy.validation import is_valid_email
    assert is_valid_email("user@example.com") == True
    assert is_valid_email("no-at-sign") == False
    assert is_valid_email("@") == True  # Weird but it's current behavior
```

## 🤝 Collaborative Links

- **Quality**: Route bug fixes to `bug-hunter`.
- **Architecture**: Route new system designs to `tech-lead`.
- **Logic**: Route refactored implementations to `backend-architect`.
- **Migration**: Route upgrade planning to `migration-upgrader`.
- **Testing**: Route test creation to `test-genius`.
- **Documentation**: Route reverse-engineered docs to `doc-writer`.

## 🚨 Failure Modes

| Situation                                | Response                                                                                |
| ---------------------------------------- | --------------------------------------------------------------------------------------- |
| Can't understand the code                | Read more. Trace the data flow. Run the code with debugger. Don't guess.                |
| No tests exist                           | Write characterization tests FIRST. They're your safety net.                            |
| Dead code might be "used externally"     | Check external consumers (CLI tools, APIs, cron jobs). Grep the entire ecosystem.       |
| Refactoring breaks undocumented behavior | That's why characterization tests exist. Write more before changing more.               |
| Too much debt to tackle                  | Prioritize: security > correctness > performance > style. Don't fix everything at once. |
| Business logic in stored procedures      | Document it. Extract to application code over time. Don't ignore it.                    |
| No documentation exists at all    | Generate docs as you explore. Every session should leave docs behind.         |
| Code depends on deprecated library | Document the dependency. Check migration path. Don't upgrade during exploration. |

## 🚩 Red Flags / Anti-Patterns

- Refactoring without reading the code first
- "Clean up" that breaks production
- Deleting dead code without verifying it's actually dead
- Rewriting from scratch instead of incremental refactoring
- Not writing characterization tests before changes
- "I'll figure out what it does as I change it"
- Ignoring stored procedures, cron jobs, or external callers
- Big-bang refactoring (rewrite everything at once)

## Common Rationalizations

| Excuse                            | Reality                                                                            |
| --------------------------------- | ---------------------------------------------------------------------------------- |
| "I can read it as I refactor"     | Reading while changing = changing while not understanding. Read first.             |
| "This code is obviously dead"     | Grep for it. Check CLI scripts, cron jobs, external callers. Verify.               |
| "Rewrite is faster than refactor" | Rewrite loses all implicit knowledge. Incremental refactoring is safer.            |
| "We don't need tests for legacy"  | Characterization tests are your safety net. Without them, refactoring is gambling. |

## ✅ Verification Before Completion

```
1. Entry points mapped: main, routes, cron jobs, CLI tools
2. Data flow traced: input → processing → output for critical paths
3. Hot spots identified: modules imported by 10+ other modules
4. Dead code catalogued: functions/files never called (verified)
5. Security issues flagged: SQL injection, hardcoded secrets, missing validation
6. Characterization tests: written for critical paths BEFORE any refactoring
7. Refactoring plan: incremental (Strangler Fig), not big-bang
```

## 💰 Quality for AI Agents

- **Structured formats**: Headers + bullets > prose.
- **Cross-reference paths**: Write `skills/XX-name/SKILL.md` not vague references.

"No completion claims without fresh verification evidence."

## Examples

### Entry Point Analysis Output

```
=== ENTRY POINTS ===
main_function: app.py (line 42) - Application startup
web_route: routes/api.py - 15 endpoints (GET/POST /api/*)
web_route: routes/web.py - 8 page routes
cron_job: cron/daily_report.py - Runs daily at 2 AM
cli_tool: scripts/migrate.py - Database migration

=== HOT SPOTS ===
utils/helpers.py - imported by 47 modules
models/user.py - imported by 32 modules
db/connection.py - imported by 28 modules

=== DEAD CODE (verified never called) ===
legacy/old_api.py - 0 references
utils/deprecated.py - marked deprecated 3 years ago
tests/ - empty directory

=== SECURITY ISSUES ===
CRITICAL: routes/api.py:89 - SQL string concatenation
HIGH: config.py:12 - Hardcoded database password
MEDIUM: routes/api.py:145 - No input validation on user_id
```

---
> Converted and distributed by [TomeVault](https://tomevault.io/claim/k1lgor) — claim your Tome and manage your conversions.
<!-- tomevault:4.0:skill_md:2026-04-15 -->

