# Phase 137: Loop Canonicalizer(前処理 SSOT) ## Status - 状態: 🔶 進行中(Phase 5 完了) ## Goal - ループ形の組み合わせ爆発を抑えるため、`AST → LoopSkeleton → (capability/routing)` の前処理を SSOT 化する。 - 既存の方針(fixture + shape guard + Fail-Fast)を維持したまま、pattern 数を増やさずにスケールさせる。 ## Phase 1(完了): 型/語彙の SSOT - 実装: `src/mir/loop_canonicalizer/mod.rs` - `LoopSkeleton` / `SkeletonStep` / `UpdateKind` - `ExitContract` / `CarrierSlot` / `CarrierRole` - `RoutingDecision` / capability tags(`CAP_MISSING_*`) - 注意: Phase 1 は「型と語彙」のみ。routing/lowering にはまだ介入しない。 ## Phase 2(完了): dev-only 観測の導入 - 入口: - Canonicalize: `src/mir/loop_canonicalizer/mod.rs`(`canonicalize_loop_expr`) - 観測ポイント: `src/mir/builder/control_flow/joinir/routing.rs`(`joinir_dev_enabled()` 配下) - 既定挙動: 不変(dev-only 観測のみ) ## Phase 3(次): Pattern 検出(Skeleton→Decision の精密化) ### 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-Fast(dev-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 細分化に備える) ## Phase 6(次): Router 委譲(dev-only / 段階投入) - 目標: “既存 router の結果” を最終SSOTとして維持したまま、dev-only で Canonicalizer の `RoutingDecision` を router 選択に使う経路を用意する。 - 方針: - まず dev-only で `RoutingDecision.chosen` を router に反映し、strict 時は parity を維持する(ズレたら Fail-Fast)。 - 既定挙動(dev flags OFF)では現行 router をそのまま使う。 ## SSOT - 設計 SSOT: `docs/development/current/main/design/loop-canonicalizer.md` - JoinIR 契約 SSOT: `docs/development/current/main/joinir-architecture-overview.md`