Refactor codebases using Design by Typed Holes methodology - iterative, test-driven refactoring with formal hole resolution, constraint propagation, and continuous validation. Use when refactoring existing code, optimizing architecture, or consolidating technical debt through systematic hole-driven development.
Systematically refactor codebases using the Design by Typed Holes meta-framework: treat architectural unknowns as typed holes, resolve them iteratively with test-driven validation, and propagate constraints through dependency graphs.
1. Create safe working branch:
git checkout -b refactor/typed-holes-v1
# CRITICAL: Never work in main, never touch .beads/ in main
2. Analyze current state and identify holes:
python scripts/discover_holes.py
# Creates REFACTOR_IR.md with hole catalog
The Refactor IR documents:
3. Write baseline characterization tests:
Create tests/characterization/ to capture exact current behavior:
# tests/characterization/test_current_behavior.py
def test_api_contracts():
"""All public APIs must behave identically post-refactor"""
for endpoint in discover_public_apis():
old_result = run_current(endpoint, test_inputs)
save_baseline(endpoint, old_result)
def test_performance_baselines():
"""Record current performance - don't regress"""
baselines = measure_all_operations()
save_json("baselines.json", baselines)
Run tests on main branch - they should all pass. These are your safety net.
For each hole (in dependency order):
1. Select next ready hole:
python scripts/next_hole.py
# Shows holes whose dependencies are resolved
2. Write validation tests FIRST (test-driven):
# tests/refactor/test_h{N}_resolution.py
def test_h{N}_resolved():
"""Define what 'resolved correctly' means"""
# This should FAIL initially
assert desired_state_achieved()
def test_h{N}_equivalence():
"""Ensure no behavioral regressions"""
old_behavior = load_baseline()
new_behavior = run_refactored()
assert old_behavior == new_behavior
3. Implement resolution:
4. Validate resolution:
python scripts/validate_resolution.py H{N}
# Checks: tests pass, constraints satisfied, main untouched
5. Propagate constraints:
python scripts/propagate.py H{N}
# Updates dependent holes based on resolution
6. Document and commit:
git add .
git commit -m "Resolve H{N}: {description}
- Tests: tests/refactor/test_h{N}_*.py pass
- Constraints: {constraints satisfied}
- Propagates to: {dependent holes}"
Generate comprehensive delta report:
python scripts/generate_report.py > REFACTOR_REPORT.md
Report includes:
Every commit must validate:
.beads/ intact in mainDesign complete when:
Every hole must be:
interface Architecture = { layers: Layer[], rules: Rule[] }Size holes using these categories:
| Size | Duration | Characteristics | Examples | |------|----------|-----------------|----------| | Nano | 1-2 hours | Simple, mechanical changes | Rename files, update imports | | Small | 4-8 hours | Single module refactor | Extract class, consolidate functions | | Medium | 1-3 days | Cross-module changes | Define interfaces, reorganize packages | | Large | 4-7 days | Architecture changes | Layer extraction, pattern implementation | | Epic | >7 days | SPLIT THIS HOLE | Too large, break into smaller holes |
Estimation Red Flags:
Split a hole when:
Splitting strategy:
Epic hole: "Refactor entire authentication system"
→ Split into:
R10_auth_interface: Define new auth interface (Medium)
R11_token_handling: Implement JWT tokens (Small)
R12_session_management: Refactor sessions (Medium)
R13_auth_middleware: Update middleware (Small)
R14_auth_testing: Comprehensive test suite (Medium)
After splitting:
python scripts/propagate.py to update graphpython scripts/holes_to_beads.py"?R1_target_architecture": "What should the ideal structure be?"
"?R2_module_boundaries": "How should modules be organized?"
"?R3_abstraction_layers": "What layers/interfaces are needed?"
Validation: Architecture tests, dependency analysis, layer violation checks
"?R4_consolidation_targets": "What code should merge?"
"?R5_extraction_targets": "What code should split out?"
"?R6_elimination_targets": "What code should be removed?"
Validation: Duplication detection, equivalence tests, dead code analysis
"?R7_test_strategy": "How to validate equivalence?"
"?R8_migration_path": "How to safely transition?"
"?R9_rollback_mechanism": "How to undo if needed?"
Validation: Test coverage metrics, migration dry-runs, rollback tests
See HOLE_TYPES.md for complete catalog.
When: Interface hole resolved with concrete types
Then: Propagate type requirements to all consumers
Example:
Resolve R6: NodeInterface = BaseNode with async run()
Propagates to:
→ R4: Parallel execution must handle async
→ R5: Error recovery must handle async exceptions
When: Implementation resolved with resource usage
Then: Propagate limits to dependent holes
Example:
Resolve R4: Parallelization with max_concurrent=3
Propagates to:
→ R8: Rate limit = provider_limit / 3
→ R7: Memory budget = 3 * single_operation_memory
When: Validation resolved with test requirements
Then: Propagate data needs upstream
Example:
Resolve R9: Testing needs 50 examples
Propagates to:
→ R7: Metrics must support batch evaluation
→ R8: Test data collection strategy needed
See CONSTRAINT_RULES.md for complete propagation rules.
| Gate | Criteria | Check | |------|----------|-------| | Gate 1: Discovery Complete | All holes cataloged, dependencies mapped | python scripts/check_discovery.py | | Gate 2: Foundation Holes | Core interfaces resolved, tests pass | python scripts/check_foundation.py | | Gate 3: Implementation | All refactor holes resolved, metrics improved | python scripts/check_implementation.py | | Gate 4: Production Ready | Migration tested, rollback verified | python scripts/check_production.py |
This skill is designed for effective Claude/LLM collaboration. Here's how to divide work:
Claude's Role:
discover_holes.py to analyze codebaseYour Role:
Claude's Role:
validate_resolution.py, check_foundation.pypython scripts/propagate.py H{N}Your Role:
Claude's Role:
Your Role:
Starting a session:
"I need to refactor [description]. Use typed-holes-refactor skill.
Start with discovery phase."
Resolving a hole:
"Resolve H3 (target_architecture). Write tests first, then implement.
Use [specific pattern/approach]."
Checking progress:
"Run check_completeness.py and show me the dashboard.
What's ready to work on next?"
Generating visualizations:
"Generate dependency graph showing bottlenecks and critical path.
Use visualize_graph.py with --analyze."
Claude CANNOT:
Claude CAN:
At session start:
"Continue typed-holes refactoring. Import beads state and
show current status from REFACTOR_IR.md."
Claude will:
You should:
bd export -o .beads/issues.jsonlWhy beads + typed holes?
# Install beads (once)
go install github.com/steveyegge/beads/cmd/bd@latest
# After running discover_holes.py
python scripts/holes_to_beads.py
# Check what's ready
bd ready --json
During hole resolution:
# Start work on a hole
bd update bd-5 --status in_progress --json
# Implement resolution
# ... write tests, implement code ...
# Validate resolution
python scripts/validate_resolution.py H3
# Close bead
bd close bd-5 --reason "Resolved H3: target_architecture" --json
# Export state
bd export -o .beads/issues.jsonl
git add .beads/issues.jsonl REFACTOR_IR.md
git commit -m "Resolve H3: Define target architecture"
Syncing holes ↔ beads:
# After updating REFACTOR_IR.md manually
python scripts/holes_to_beads.py # Sync changes to beads
# After resolving holes
python scripts/holes_to_beads.py # Update bead statuses
Cross-session continuity:
# Session start
bd import -i .beads/issues.jsonl
bd ready --json # Shows ready holes
python scripts/check_completeness.py # Shows overall progress
# Session end
bd export -o .beads/issues.jsonl
git add .beads/issues.jsonl
git commit -m "Session checkpoint: 3 holes resolved"
Bead advantages:
bd deps bd-5All scripts are in scripts/:
discover_holes.py - Analyze codebase and generate REFACTOR_IR.mdnext_hole.py - Show next resolvable holes based on dependenciesvalidate_resolution.py - Check if hole resolution satisfies constraintspropagate.py - Update dependent holes after resolutiongenerate_report.py - Create comprehensive delta reportcheck_discovery.py - Validate Phase 0 completeness (Gate 1)check_foundation.py - Validate Phase 1 completeness (Gate 2)check_implementation.py - Validate Phase 2 completeness (Gate 3)check_production.py - Validate Phase 3 readiness (Gate 4)check_completeness.py - Overall progress dashboardvisualize_graph.py - Generate hole dependency visualizationholes_to_beads.py - Sync holes with beads issuesRun any script with --help for detailed usage.
This skill uses its own principles:
| Typed Holes Principle | Application to Refactoring | |-----------------------|----------------------------| | Typed Holes | Architectural unknowns cataloged with types | | Constraint Propagation | Design constraints flow through dependency graph | | Iterative Refinement | Hole-by-hole resolution cycles | | Test-Driven Validation | Tests define correctness | | Formal Completeness | Gates verify design completeness |
We use the system to refactor the system.
For complex scenarios, see:
# 1. Setup
git checkout -b refactor/typed-holes-v1
python scripts/discover_holes.py
# 2. Write baseline tests
# Create tests/characterization/test_*.py
# 3. Resolve first hole
python scripts/next_hole.py # Shows H1 is ready
# Write tests/refactor/test_h1_*.py (fails initially)
# Refactor code until tests pass
python scripts/validate_resolution.py H1
python scripts/propagate.py H1
git commit -m "Resolve H1: ..."
# 4. Repeat for each hole
# ...
# 5. Generate report
python scripts/generate_report.py > REFACTOR_REPORT.md
Symptom: Tests that captured baseline behavior now fail
Resolution:
git diff to see what changed ``python # Update baseline with reason save_baseline("v2_api", new_behavior, reason="Switched to async implementation") ``
Prevention: Run characterization tests before AND after each hole resolution.
Symptom: Stuck on a hole for >3 days, unclear how to proceed
Resolution:
``bash python scripts/visualize_graph.py --analyze # Look for unresolved dependencies ``
``bash # Original: R4_consolidate_all (Epic, 10+ days) # Split into: R4a_consolidate_parsers (Medium, 2 days) R4b_consolidate_validators (Small, 1 day) R4c_consolidate_handlers (Medium, 2 days) ``
``bash python scripts/visualize_graph.py # Look for cycles: R4 → R5 → R6 → R4 ``
Escalation: If still stuck after 5 days, consider alternative refactoring approach.
Symptom: Cannot satisfy all constraints simultaneously
Example:
Resolution Framework:
``markdown C1 requires: Keep synchronous operations C5 requires: Switch to async operations → Contradiction: Can't be both sync and async ``
| Option | C1 | C5 | Tradeoff | |--------|----|----|----------| | A: Keep sync | ✓ | ✗ | No performance gain | | B: Switch to async | ✗ | ✓ | Breaking change | | C: Add async, deprecate sync | ⚠️ | ✓ | Migration burden |
```markdown ## Constraint Resolution: C1 vs C5
Decision: Relax C1 to allow async migration Rationale: Performance critical for user experience Migration: 3-month deprecation period for sync API Approved by: [Stakeholder], [Date] ```
Symptom: visualize_graph.py shows cycles
Example:
R4 (consolidate parsers) → depends on R6 (define interface)
R6 (define interface) → depends on R4 (needs parser examples)
Resolution strategies:
`` H0_parser_analysis: Analyze existing parsers (no dependencies) R6_interface: Define interface using H0 analysis R4_consolidate: Implement using R6 interface ``
`` R6_interface_v1: Initial interface (simple) R4_consolidate: Implement with v1 interface R6_interface_v2: Refine based on R4 learnings ``
Prevention: Define architecture holes before implementation holes.
Symptom: Feeling stuck, no commits, uncertain how to proceed
Resolution checklist:
python scripts/check_completeness.pypython scripts/visualize_graph.py --analyzeReset protocol: If still stuck, revert to last working state and try different approach.
Symptom: Hole taking 3x longer than estimated
Analysis:
bd update bd-5 --note "Revised estimate: 5 days (was 2)"Learning: Track actual vs estimated time in REFACTOR_REPORT.md for future reference.
Begin with Phase 0: Discovery. Always work in a branch. Test first, refactor second.