feat(mir): Phase 137-5 - Decision Policy SSOT化完了

## 目的
Canonicalizer の RoutingDecision.chosen を「lowerer 選択の最終結果」にする
(構造クラス名ではなく ExitContract ベースの決定)

## 実装内容

### 1. Canonicalizer の決定ロジック修正
- `src/mir/loop_canonicalizer/mod.rs`
  - `skip_whitespace` パターン認識で ExitContract (has_break=true) を考慮
  - Pattern3IfPhi → Pattern2Break に修正(構造は似ているが break あり)
  - 単体テスト更新(Pattern2Break 期待に変更)

### 2. Parity 検証テスト修正
- `src/mir/builder/control_flow/joinir/routing.rs`
  - `test_parity_check_mismatch_detected` → `test_parity_check_skip_whitespace_match`
  - Canonicalizer と Router の一致を検証(ミスマッチ検出からマッチ検証へ)
  - Phase 137-5 の SSOT 原則を反映

### 3. ドキュメント更新
- `docs/development/current/main/design/loop-canonicalizer.md`
  - Phase 137-5: Decision Policy SSOT セクション追加
  - ExitContract 優先の原則を明記
  - skip_whitespace の例を追加

- `docs/development/current/main/phases/phase-137/README.md`
  - Phase 4 完了マーク追加
  - Phase 5 完了セクション追加(実装・検証・効果)

## 検証結果
-  単体テスト: `cargo test --release --lib loop_canonicalizer::tests` (11/11 passed)
-  Parity テスト: `cargo test --release --lib 'routing::tests::test_parity'` (2/2 passed)
-  Strict モード: `HAKO_JOINIR_STRICT=1` で skip_whitespace parity OK

## 効果
- Router と Canonicalizer の pattern 選択が一致
- ExitContract が pattern 決定の SSOT として明確化
- 構造的特徴(if-else 等)は notes に記録(将来拡張に備える)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-16 06:17:03 +09:00
parent 9ea15e8417
commit 58f66e3fa2
4 changed files with 61 additions and 15 deletions

View File

@ -1,7 +1,7 @@
# Phase 137: Loop Canonicalizer前処理 SSOT
## Status
- 状態: 🔶 進行中Phase 2 完了)
- 状態: 🔶 進行中Phase 3 完了)
## Goal
- ループ形の組み合わせ爆発を抑えるため、`AST → LoopSkeleton → (capability/routing)` の前処理を SSOT 化する。
@ -24,8 +24,32 @@
## Phase 3: Pattern 検出Skeleton→Decision の精密化)
- 目標: `skip_whitespace` を Skeleton から安定に識別し、`RoutingDecision.chosen``missing_caps` を期待通りに固定する。
- 注意: routing/lowering の変更は dev-only の観測結果が固まってから。
### Phase 3完了: `skip_whitespace` の安定認識
- 実装: `src/mir/loop_canonicalizer/mod.rs``try_extract_skip_whitespace_pattern`
- 効果: `tools/selfhost/test_pattern3_skip_whitespace.hako``Pattern3IfPhi` として認識し、`missing_caps=[]` を固定できるようになったdev-only 観測)。
注意:
- routing/lowering の変更は “パリティ検証Phase 4” を挟んでから行う(既定挙動は不変)。
## Phase 4完了: Router パリティ検証dev-only / Fail-Fast
- 目標: 既存 JoinIR ルータ(現行の Pattern 選択)と Canonicalizer の `RoutingDecision` が一致することを検証し、ズレた場合は理由付きで Fail-Fastdev-only
- 目的: いきなり routing を差し替えず、安全に "観測→一致→段階投入" の導線を作る。
- 実装: `src/mir/builder/control_flow/joinir/routing.rs``verify_router_parity`
## Phase 5完了: Decision Policy SSOT 化
- 目標: `RoutingDecision.chosen` を「lowerer 選択の最終結果」にする(構造クラス名ではなく)
- 実装:
- `src/mir/loop_canonicalizer/mod.rs`: ExitContract に基づく pattern 選択
- `has_break=true``Pattern2Break`(構造的に Pattern3 に似ていても)
- `has_continue=true``Pattern4Continue`
- 検証: `tools/selfhost/test_pattern3_skip_whitespace.hako` で parity OK`HAKO_JOINIR_STRICT=1`
- 効果:
- Router と Canonicalizer の一致性確保
- ExitContract が pattern 選択の決定要因として明確化
- 構造的特徴if-else 等)は `notes` に記録(将来の Pattern 細分化に備える)
## SSOT