typed-holes-refactor について
typed-holes-refactorは、Claude/LLMとの協業を想定したコードベースのリファクタリングスキルです。設計上の未知点を明示し、依存順の解決、テスト先行の検証、制約追跡、最終レポート作成を行います。
主な機能
- 01リファクタリング課題と依存関係の整理
- 02依存順に課題を解決
- 03特性テストと検証テストの活用
- 04依存先への制約伝播
- 05リファクタリング差分レポートの生成
活用シーン
- 01設計上の疑問を含むリファクタリングの計画
- 02コード変更中の既存動作の維持
- 03複数セッションにわたる検証と依存関係の追跡
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ rand/ cc-polymath --skill typed-holes-refactorインストール後、Claude Code で/typed-holes-refactorを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdreferences/CONSTRAINT_RULES.mdEXAMPLES.mdHOLE_TYPES.mdVALIDATION_PATTERNS.mdscripts/check_completeness.pycheck_discovery.pycheck_foundation.pycheck_implementation.pycheck_production.pydiscover_holes.pygenerate_report.pyholes_to_beads.pynext_hole.pypropagate.pyvalidate_resolution.pyvisualize_graph.py詳細
型付きホールによるリファクタリング
Design by Typed Holes メタフレームワークを使用して、コードベースを体系的にリファクタリングします。アーキテクチャ上の未知事項を型付きホールとして扱い、テスト駆動の検証を行いながら反復的に解決し、依存関係グラフを通じて制約を伝播させます。
コアワークフロー
フェーズ 0:ホールの発見とセットアップ
1. 安全な作業ブランチを作成する:
git checkout -b refactor/typed-holes-v1
# CRITICAL: Never work in main, never touch .beads/ in main
2. 現在の状態を分析し、ホールを特定する:
python scripts/discover_holes.py
# Creates REFACTOR_IR.md with hole catalog
リファクタリング IR には次の内容が記録されます。
- 現在の状態のホール:現在のシステムについて何が不明ですか?
- リファクタリングのホール:理想の状態に到達するには、何を解決する必要がありますか?
- 制約:何を維持、改善、または保持する必要がありますか?
- 依存関係:どのホールが、ほかのどのホールを妨げていますか?
3. ベースラインとなる特性テストを作成する:
現在の動作を正確に記録するため、tests/characterization/ を作成します。
# 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)
main ブランチでテストを実行します。すべて合格するはずです。これらが安全網になります。
フェーズ 1~N:反復的なホールの解決
各ホールについて、依存関係の順に進めます。
1. 次に解決可能なホールを選択する:
python scripts/next_hole.py
# Shows holes whose dependencies are resolved
2. まず検証テストを作成する(テスト駆動):
# 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. 解決を実装する:
- テストに合格するようコードをリファクタリングします
- 特性テストが引き続き合格するようにします
- 明確なメッセージを添えて、段階的にコミットします
4. 解決を検証する:
python scripts/validate_resolution.py H{N}
# Checks: tests pass, constraints satisfied, main untouched
5. 制約を伝播させる:
python scripts/propagate.py H{N}
# Updates dependent holes based on resolution
6. 文書化してコミットする:
git add .
git commit -m "Resolve H{N}: {description}
- Tests: tests/refactor/test_h{N}_*.py pass
- Constraints: {constraints satisfied}
- Propagates to: {dependent holes}"
最終フェーズ:レポート
包括的な差分レポートを生成する:
python scripts/generate_report.py > REFACTOR_REPORT.md
レポートには次の内容が含まれます。
- 検証の証拠を含むホール解決の概要
- 指標の差分(LOC、複雑度、カバレッジ、パフォーマンス)
- 動作の分析(意図的な変更を文書化)
- 制約の検証(すべて満たされていること)
- リスク評価と移行ガイド
主要な原則
1. すべてをテスト駆動で進める
- 実装前に検証基準を作成する
- テストによって「正しい解決」を定義する
- 特性テストは最優先事項です。決して失敗させないでください
2. ホール駆動で進める
- 依存関係の順にホールを解決する
- 解決するたびに制約を伝播させる
- すべてをリファクタリング IR に正式に記録する
3. 継続的に検証する
すべてのコミットで、次の項目を検証する必要があります。
- ✅ 特性テストに合格する(動作が維持されている)
- ✅ 解決テストに合格する(ホールが正しく解決されている)
- ✅ 制約が満たされている
- ✅ main ブランチに変更を加えていない
- ✅ main の
.beads/がそのまま保たれている
4. 構造的に安全な方法を取る
- リファクタリングブランチでのみ作業する
- main は読み取り専用の参照先とする
- Beads は変更できない過去の成果物です
5. 形式的な完全性
次の条件を満たすと、設計は完了です。
- すべてのホールが解決され、検証されている
- すべての制約が満たされている
- すべてのフェーズゲートを通過している
- 指標が改善または維持されている
ホールの品質フレームワーク
適切なホールの SMART 基準
すべてのホールは、次の条件を満たす必要があります。
-
具体的:明確で範囲が定められ、具体的な答えがある質問である
- ✓ 良い例:「API 層でのエラー処理はどのようにすべきか?」
- ✗ 悪い例:「コードをどう改善するか?」
-
測定可能:検証可能な基準がある
- ✓ 良い例:「重複率を 60% から <15% に減らす」
- ✗ 悪い例:「コードをより良くする」
-
達成可能:入手可能な情報で解決できる
- ✓ 良い例:「解析ロジックを独立したモジュールに切り出す」
- ✗ 悪い例:「将来の要件をすべて予測する」
-
関連性がある:リファクタリングの有意義な進展を妨げている
- ✓ 良い例:「コアインターフェースを定義する(ほかの 5 つのホールを妨げている)」
- ✗ 悪い例:「変数の命名規則を決める」
-
型が定義されている:解決のための型や構造が明確である
- ✓ 良い例:
interface Architecture = { layers: Layer[], rules: Rule[] } - ✗ 悪い例:「何らかの構造?」
- ✓ 良い例:
ホール推定フレームワーク
以下のカテゴリを使ってホールの規模を見積もります。
| 規模 | 期間 | 特徴 | 例 |
|---|---|---|---|
| Nano | 1-2 時間 | シンプルで機械的な変更 | ファイル名の変更、インポートの更新 |
| Small | 4-8 時間 | 単一モジュールのリファクタリング | クラスの抽出、関数の統合 |
| Medium | 1-3 日 | モジュール間の変更 | インターフェースの定義、パッケージの再編成 |
| Large | 4-7 日 | アーキテクチャの変更 | レイヤーの抽出、パターンの実装 |
| Epic | >7 日 | このホールを分割してください | 大きすぎるため、より小さなホールに分割 |
見積もり時の危険信号:
- 依存関係が3つを超える → Medium以上の可能性があります
- 検証方法が不明確 → 調査時間を追加します
- 新しいパターン/ツール → 学習にかかる時間を追加します
ホールの分割ガイドライン
次の場合はホールを分割します:
- 見積もりが7日を超える
- 依存関係が5つを超える
- 検証基準が不明確
- 複数の異なる関心事が混在している
分割戦略:
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)
分割後:
- REFACTOR_IR.md の依存関係を更新します
python scripts/propagate.pyを実行してグラフを更新します- beads と再同期します:
python 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?"
検証: アーキテクチャテスト、依存関係の分析、レイヤー違反のチェック
実装のホール
"?R4_consolidation_targets": "What code should merge?"
"?R5_extraction_targets": "What code should split out?"
"?R6_elimination_targets": "What code should be removed?"
検証: 重複の検出、同等性テスト、デッドコードの分析
品質のホール
"?R7_test_strategy": "How to validate equivalence?"
"?R8_migration_path": "How to safely transition?"
"?R9_rollback_mechanism": "How to undo if needed?"
検証: テストカバレッジ指標、移行のドライラン、ロールバックテスト
完全なカタログについては、HOLE_TYPES.md を参照してください。
制約の伝播ルール
ルール1:インターフェースの解決 → 型制約
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
ルール2:実装 → パフォーマンス制約
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
ルール3:検証 → テスト要件
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
完全な伝播ルールについては、CONSTRAINT_RULES.md を参照してください。
成功の指標
週ごとの進捗
- 2〜4個のホールを解決
- すべてのテストが合格
- 制約を満たしている
- 改善を測定できる
危険信号(停止して再評価)
- ❌ 特性テストが失敗する
- ❌ 制約の範囲内でホールを解決できない
- ❌ 制約同士が矛盾している
- ❌ 3日以上進捗がない
- ❌ メインブランチを誤って変更した
検証ゲート
| ゲート | 基準 | チェック |
|---|---|---|
| ゲート1:調査完了 | すべてのホールをカタログ化し、依存関係をマッピング済み | python scripts/check_discovery.py |
| ゲート2:基盤ホール | コアインターフェースを解決済みで、テストが合格 | python scripts/check_foundation.py |
| ゲート3:実装 | すべてのリファクタリングホールを解決済みで、指標が改善 | python scripts/check_implementation.py |
| ゲート4:本番環境への準備完了 | 移行をテスト済みで、ロールバックを検証済み | python scripts/check_production.py |
Claude を活用したワークフロー
このスキルは、Claude/LLM との効果的な連携を目的に設計されています。作業の分担方法は次のとおりです。
フェーズ0:調査
Claude の役割:
discover_holes.pyを実行してコードベースを分析する- コード分析に基づいてホールを提案する
- REFACTOR_IR.md の初期構成を生成する
- 現在の動作を記録する特性テストを作成する
- テストインフラストラクチャをセットアップする
あなたの役割:
- ホールの範囲が適切か確認する
- どのホールから取り組むか優先順位を付ける
- REFACTOR_IR.md をレビューして承認する
- 重要な制約を定義する
フェーズ1〜N:ホールの解決
Claude の役割:
- 実装前に解決テスト(TDD)を作成する
- テストに合格するようホールの解決を実装する
- 検証スクリプトを実行する:
validate_resolution.py、check_foundation.py - 解決の詳細を REFACTOR_IR.md に反映する
- 制約を伝播する:
python scripts/propagate.py H{N} - 変更内容を記録するコミットメッセージを生成する
あなたの役割:
- アーキテクチャ上の決定を行う(どのパターンを使うか、どのアプローチを採るか)
- リスクを評価し、制約の優先順位を決める
- コード変更の正確性をレビューする
- 完了後、main へのマージを承認する
フェーズ最終:レポート
Claude の役割:
- 包括的な REFACTOR_REPORT.md を作成する
- すべてのメトリクスの差分を記録する
- すべての検証エビデンスを一覧にする
- 移行ガイドを作成する
- PR の説明を準備する
あなたの役割:
- レポートの正確性を最終確認する
- 本番環境へのデプロイを承認する
- リファクタリング後の振り返りを行う
効果的なプロンプトのパターン
セッションの開始時:
"I need to refactor [description]. Use typed-holes-refactor skill.
Start with discovery phase."
穴の解決:
"Resolve H3 (target_architecture). Write tests first, then implement.
Use [specific pattern/approach]."
進捗の確認:
"Run check_completeness.py and show me the dashboard.
What's ready to work on next?"
ビジュアライゼーションの生成:
"Generate dependency graph showing bottlenecks and critical path.
Use visualize_graph.py with --analyze."
Claude の制限事項
Claude にできないこと:
- 主観的なアーキテクチャ上の決定(あなたが判断する必要があります)
- ビジネス上の重要な制約の特定(あなたが指定する必要があります)
- 外部サービスを必要とするテストの実行(モックを使用するか、あなたが実行してください)
- main へのマージ(あなたが承認してマージする必要があります)
Claude にできること:
- コードを分析し、穴を提案する
- 包括的なテストスイートを作成する
- あなたの制約の範囲内で解決策を実装する
- レポートとドキュメントを生成する
- セッションをまたいで進捗を追跡する(beads + REFACTOR_IR.md を介して)
複数セッションにわたる継続性
セッション開始時:
"Continue typed-holes refactoring. Import beads state and
show current status from REFACTOR_IR.md."
Claude は以下を行います:
- REFACTOR_IR.md を読み、現在の状態を把握する
- 解決済みの穴を確認する
- 次に対応可能な穴を特定する
- 前のセッションが終了した箇所から再開する
あなたが行うこと:
- REFACTOR_IR.md と .beads/ を git にコミットした状態に保つ
- セッション終了時に beads の状態をエクスポートする:
bd export -o .beads/issues.jsonl - Claude が完全なコンテキストを把握できるよう、開始前に /context を使用する
Beads との統合
beads と型付きホールを組み合わせる理由:
- Beads はセッションをまたいで課題を追跡します(作業の消失を防ぎます)
- ホールはリファクタリング固有の状態(依存関係、制約)を追跡します
- 組み合わせることで、長期にわたるリファクタリングの継続性を完全に確保できます
セットアップ
# 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
ワークフローとの統合
ホールの解決中:
# 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"
ホールと 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
セッションをまたいだ継続性:
# 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 の利点:
- 数日から数週間にわたる作業を追跡します
- 依存関係グラフを表示します:
bd deps bd-5 - コンテキストの喪失を防ぎます
- プロジェクト全体の管理と統合します
スクリプト一覧
すべてのスクリプトは scripts/ にあります:
discover_holes.py- コードベースを分析して REFACTOR_IR.md を生成するnext_hole.py- 依存関係に基づき、次に解決可能なホールを表示するvalidate_resolution.py- ホールの解決が制約を満たしているか確認するpropagate.py- 解決後に依存するホールを更新するgenerate_report.py- 包括的な差分レポートを作成するcheck_discovery.py- フェーズ 0 の完了状況を検証する(ゲート 1)check_foundation.py- フェーズ 1 の完了状況を検証する(ゲート 2)check_implementation.py- フェーズ 2 の完了状況を検証する(ゲート 3)check_production.py- フェーズ 3 の準備状況を検証する(ゲート 4)check_completeness.py- 全体の進捗ダッシュボードvisualize_graph.py- ホールの依存関係を可視化するholes_to_beads.py- ホールと beads の課題を同期する
詳しい使い方を確認するには、任意のスクリプトを --help 付きで実行してください。
メタ一貫性
このスキルは独自の原則を使用しています:
| 型付きホールの原則 | リファクタリングへの適用 |
|---|---|
| 型付きホール | アーキテクチャ上の未確定事項を型ごとにカタログ化する |
| 制約の伝播 | 設計上の制約を依存関係グラフ全体に伝播させる |
| 反復的な改善 | ホールごとに解決サイクルを繰り返す |
| テスト駆動の検証 | テストによって正しさを定義する |
| 形式的な完全性 | ゲートによって設計の完全性を検証する |
このシステムを使って、システムをリファクタリングします。
応用トピック
複雑なシナリオについては、以下を参照してください:
- HOLE_TYPES.md - 詳細なホール分類
- CONSTRAINT_RULES.md - 伝播ルールの全容
- VALIDATION_PATTERNS.md - さまざまなホールの種類に対するテストパターン
- EXAMPLES.md - 一連の手順を網羅した例
クイックスタートの例
# 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
トラブルシューティング
特性化テストが失敗する
症状: ベースラインの動作を記録したテストが失敗するようになりました
解決方法:
- 変更を元に戻します:
git diffで変更内容を確認します - 原因を調査します: どの動作が、なぜ変わったのでしょうか?
- 判断の流れ:
- 意図的な変更: ドキュメントを添えてベースラインを更新します
# 理由を添えてベースラインを更新 save_baseline("v2_api", new_behavior, reason="Switched to async implementation") - 意図しないリグレッション: コードを修正し、テストを通過させます
- 意図的な変更: ドキュメントを添えてベースラインを更新します
予防策: 各ホールを解決する前と後に、特性化テストを実行してください。
ホールを解決できない
症状: 3 日以上ホールに行き詰まり、進め方がはっきりしません
解決方法:
-
依存関係を確認する: 本当に解決済みですか?
python scripts/visualize_graph.py --analyze # Look for unresolved dependencies -
制約を見直す: 矛盾していませんか?
- 例: C1「すべての動作を維持する」+C5「API コントラクトを変更する」→ 矛盾しています
- 修正: ステークホルダーと制約を再交渉します
-
ホールを分割する: ホールが大きすぎる場合
# 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) -
循環依存を確認する:
python scripts/visualize_graph.py # Look for cycles: R4 → R5 → R6 → R4- 修正: 中間ホールを導入するか、依存関係を再定義して循環を解消します
エスカレーション: 5 日経っても行き詰まっている場合は、別のリファクタリング方法を検討してください。
矛盾する制約
症状: すべての制約を同時に満たせません
例:
- C1:「現在の動作を正確に維持する」(後方互換性)
- C5:「応答時間を 50% 短縮する」(パフォーマンス改善)
- 現在の動作には、遅い同期処理が含まれています
解決の枠組み:
-
矛盾を特定する:
C1 requires: Keep synchronous operations C5 requires: Switch to async operations → Contradiction: Can't be both sync and async -
優先順位を交渉する:
選択肢 C1 C5 トレードオフ A: 同期を維持 ✓ ✗ パフォーマンス向上なし B: 非同期に切り替える ✗ ✓ 破壊的変更 C: 非同期を追加し、同期を非推奨にする ⚠️ ✓ 移行の負担 -
解決方針を選択する:
- 制約を緩和する: C1 を「可能な範囲で動作を維持する」に変更します
- 移行期間を設ける: C を 2 回のリリースに分けて実装します
- フェーズに分ける: フェーズ 1(C1)、フェーズ 2(C5)
-
決定を記録する:
## 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]
循環依存
症状: visualize_graph.py に循環が表示されます
例:
R4 (consolidate parsers) → depends on R6 (define interface)
R6 (define interface) → depends on R4 (needs parser examples)
解決策:
-
中間ホールを導入する:
H0_parser_analysis: Analyze existing parsers (no dependencies) R6_interface: Define interface using H0 analysis R4_consolidate: Implement using R6 interface -
依存関係を再定義する:
- R4 は実際には R6 を必要としないかもしれません
- または、R6 が必要とするのは R4 の一部だけかもしれません(R4 を分割します)
-
反復的な改善を受け入れる:
R6_interface_v1: Initial interface (simple) R4_consolidate: Implement with v1 interface R6_interface_v2: Refine based on R4 learnings
予防策: 実装ホールより先に、アーキテクチャホールを定義してください。
3 日以上進展がない
症状: 行き詰まり、コミットがなく、進め方が分かりません
解決チェックリスト:
-
REFACTOR_IR.md を見直す: ホールは明確に定義されていますか(SMART 基準)?
- そうでない場合: より具体的になるようホールを書き直します
-
ホールの規模を確認する: 現在のホールの見積もりは 7 日を超えていますか?
- はいの場合: より小さなホールに分割します
-
ダッシュボードを実行する:
python scripts/check_completeness.py- ブロックされているホールに取り組んでいませんか?
- 代わりに、着手可能なホールに切り替えます
-
依存関係を可視化する:
python scripts/visualize_graph.py --analyze- ボトルネックを特定します
- 並行して作業できる機会を探します
-
制約を見直す: 達成可能ですか?
- 必要に応じて再交渉します
-
外部レビューを依頼する:
- REFACTOR_IR.md を同僚と共有します
- アプローチについてフィードバックをもらいます
-
別の方法を検討する: このリファクタリングは実現不可能かもしれません
- 理由を記録します
- 別のアプローチを提案します
リセット手順: それでも行き詰まっている場合は、最後に正常に動作した状態に戻し、別の方法を試してください。
見積もりの失敗
症状:穴の修正に見積もりの3倍の時間がかかる
分析:
-
見積もりに失敗したのはなぜですか?
- 複雑さを過小評価していた
- 予期しない依存関係があった
- 要件が不明確だった
- 技術的な問題があった(ツールの問題、インフラストラクチャ)
-
直ちに行う対応:
- REFACTOR_IR.md を更新して、見積もりを修正します
- 7日を超える場合は、穴を分割します
- beads を更新します:
bd update bd-5 --note "Revised estimate: 5 days (was 2)"
-
今後の改善点:
- 実際にかかった時間を使って、今後の見積もりを調整します
- 調査用の余裕(20%の追加時間)を設けます
- IR に不確実性を記載します:「見積もり:2~4日(不確実性が高い)」
学び:今後の参考として、REFACTOR_REPORT.md に実績時間と見積もり時間を記録します。
フェーズ0:調査から始めます。必ずブランチで作業します。まずテストを行い、その後にリファクタリングします。