---
Status: Active
Scope: CorePlan composition（Feature合成→Normalizerへ、仕様不変で段階導入）
Related:
- docs/development/current/main/design/coreplan-migration-roadmap-ssot.md
- docs/development/current/main/design/coreplan-skeleton-feature-model.md
- docs/development/current/main/design/post-phi-final-form-ssot.md
- docs/development/current/main/design/exitkind-cleanup-effect-contract-ssot.md
- docs/development/current/main/phases/phase-29ae/README.md
---

# Phase 29ao: CorePlan composition from Skeleton/Feature (Step-C/D)

Goal: DomainPlan の “complete pattern” に寄り過ぎない形で、**Skeleton + Feature** から `CorePlan` を合成していく（仕様不変で段階導入）。

Gate（SSOT）:
- `./tools/smokes/v2/profiles/integration/joinir/phase29ae_regression_pack_vm.sh`

## P0: Composer scaffold（未接続・仕様不変）✅

- 指示書: `docs/development/current/main/phases/phase-29ao/P0-COREPLAN-COMPOSER-SCAFFOLD-INSTRUCTIONS.md`
- ねらい: `CanonicalLoopFacts`（projection済み）→ `CorePlan` 合成の入口を 1 箇所に作り、以後の実装を “合成だけ” に寄せる

## P1: Composer API決定 + bridge（未接続・仕様不変）✅

- 指示書: `docs/development/current/main/phases/phase-29ao/P1-COREPLAN-COMPOSER-API-BRIDGE-INSTRUCTIONS.md`
- ねらい:
  - `CorePlan` が `BasicBlockId/ValueId/Frag` を要求するため、Facts→合成の段階で **どこが allocation を持つか**を SSOT として固定する
  - まずは “bridge” として、composer が `CanonicalLoopFacts` から `DomainPlan`（既存語彙）を構築して `PlanNormalizer` を呼べる形まで整える（未接続のまま）

## Next（planned）

- P2: CoreLoop skeleton（preheader/header/body/exit）を `CorePlan` 語彙で生成（effects/phis/frag は “最小で正しい”）
- P3: ExitMap presence を `Frag/ExitMap` と結ぶ（break/continue/return を feature 合成へ寄せる）
- P4: Cleanup presence を ExitKind 単位で wire（effect/cleanup SSOT に従う、観測差分なし）
- P5: ValueJoin presence を post-phi SSOT に沿って wire（局所 verify から）
