# Phase 20.15 — Selfhost α(Freeze‑First + Dual‑Run) Purpose - 「削減%」ではなく「契約凍結+二重運用」で自立へ進める初回フェーズ。 - JSON v0 MIR スキーマと Core VM 最小意味論を固定し、Selfhost 最小ラインを quick に導線。 Strategy - Freeze the contracts first: JSON v0 keys/型/operation 語彙と Core 最小 ops を docs/スモークで固定。 - Dual‑Run migration: 同契約に対して Rust/LLVM と Hakorune(Core) を並走(ENV/プロファイルで切替)。 Goals (high‑level) - Core VM: mir_call(Array/Map/Extern/Method 代表)と const/binop/compare/branch/jump/phi/load/store/copy/typeop の Fail‑Fast とタグ整備。 - Builder: 単一パス emit を維持し、used‑before‑def を reader/validator で Fail‑Fast。 - Canaries: emit→Core の return/binop/if/map/array 正負例を quick に追加(既定OFF)。 - Front: adopt/noop/fail の契約を薄く定義(既定OFF、将来の切替点)。 Non‑Goals (20.15) - 既定挙動の変更はしない(すべて gate 配下)。広域リファクタは行わない。 Acceptance Criteria - 契約準拠 canary(return/binop/if/array/map)が `SMOKES_ENABLE_2015=1` で緑。 - Core の新規 mir_call カバレッジに安定タグが付与され、負例は Fail‑Fast で固定。 - Builder→JSON v0 で used‑before‑def を出さない(reader/validator で検出可能)。 Status (Final) - quick/core canaries(emit→Core): 正例/負例 含む代表4本が全て PASS - map_len_get(rc=7), phi_diamond(rc固定) - array_set_oob_fail → [core/mir_call] array set out of bounds(非0) - map_get_missing_fail → [core/mir_call] map get missing key(非0) - JSON v0 schema を docs/development/architecture/mir_json_v0_schema.md に固定 Gates (default OFF) - SMOKES_ENABLE_2015=1 — 20.15 canary 有効化 - HAKO_CORE_2015=1 — Core の拡張パスを許可 Notes - ENV は HAKO_* 優先・NYASH_* は互換(docs で alias を明記)。 - 詳細戦略: `docs/private/roadmap/phases/FROZEN_TOOLCHAIN_STRATEGY.md`