# Current Task — Phase 20.45 (self‑host E2E 1/2) This document is intentionally concise (≤ 500 lines). Detailed history and per‑phase plans are kept under docs/private/roadmap/. See links below. Focus (now) - Hako MirBuilder → v1 MIR → hv1 実行を PRIMARY に固定(no‑fallback)。 - Array/Map の rc 実行を段階移行(builder‑only → rc)。 - Provider 実行(emit/codegen)を恒常運用できる形に整備(代表は Hako PRIMARY で緑)。 Remaining (20.45) - Array/Map rc 移行(段階) - v0 ローダに newbox/boxcall の最小受理を追加、または provider emit を v1 スキーマへ寄せるトグルを追加(どちらか一方で可)。 - lowers 生成側の size 標準化(len/length は受理側で別名吸収)。 - Provider 直行の幅出し - 三項・match・論理・複数 block の rc カナリを拡充。 - 逆引き/スキャナ統一のスイープ(小粒継続) - If/Compare VarInt/VarVar、Return BinOp/Logical に PatternUtilBox/JsonFragBox を適用。 - ループ系の JsonFragBox 化(ProgScan 置換を段階導入)。 Progress (today) - PRIMARY no-fallback reps 拡張(canary 追加・緑化) - Return(Int)(runner_min 経由): PASS - Return(BinOp Int+Int)(runner_min 経由): PASS - Array.size(MirBuilder 経由): PASS - Logical(OR の代表、MirBuilder 経由): PASS(AND は次フェーズで検証/整備) - Load/Store(runner_min v1 → hv1 inline): PASS - 修正 - lower_return_int_box.hako: MIR v0 形状を正規化(functions[]=…, name="main", blocks.id) - lower_return_binop_box.hako: 同上(v0 形状) - runner_min_box.hako: Return(BinOp) を採用 - phase2043 runner_min カナリの alias を修正(Runner→BuilderRunnerMinBox) Next Steps (ordered) 1) Hako MirBuilder PRIMARY(HAKO_PRIMARY_NO_FALLBACK=1)で代表(Return/If/Compare/Logical/Match/Ternary/Loop/Array/Map)を順に緑化。 2) 生成側 size 標準化の横展開(rc カナリに切替)。 3) Provider 幅出し(三項・match・論理・複数 block)rc カナリの追加。 4) 逆引き/スキャナ統一スイープの継続(If/Compare/Return)。 5) ループ系の JsonFragBox 化(安全サブセットから)。 6) Logical(AND) の PRIMARY 化(必要に応じ Lower の堅牢化)。 Hotfix Plan — Using/Prelude Unification (Self‑Host) - Problem: .hako を NyashParser に通す経路でパース落ち(Invalid expression)。 - Decision: プレリュードは“テキスト統合(merge_prelude_text)”に一本化。AST マージは撤退。 - Resolver 入口は共通(alias/modules/packages/builtin)。 - 以降はメインの言語に応じて実行器へ渡す(Hako→Hakorune VM / MIR→Core)。 - NyashParser は Nyash コードのみ。Hako は Nyash VM 経路に入れない(Fail‑Fast)。 Action Items (20.38) - P1 C‑ABI ブリッジ(既定OFF) - Hako provider→Rust extern_provider へ最小接続(emit/codegen)。 - ハーネスのタグ用シム(test_runner)を撤去できる状態にする。 - P2 v1 Dispatcher IR 完了+φテーブル堅牢化 - V1SchemaBox.get_function_ir を構造IRで返却(blocks/phi_table)。 - ループは IR 反復に完全切替、φ は entry 適用(命令ループから除去)。 - 複数φ/複数incoming/空白改行混在を canary で固定。 - P3 Verify 既定整流(完了) - v1→Hakorune を既定ON、Core は診断 fallback。末尾数値抽出で rc を一意化。 - include ポリシー quick=ERROR を維持(ドキュメントと一致)。 - P4 Resolver/alias 仕上げ - lang/src/vm/** の alias を監査し、直参照を払拭。normalize/trace ログは最小に整流。 - P5 Docs 反映 - phase‑20.38 のトグル/受け入れ条件/撤去予定のシムを反映。φ entry SSOT は IR 完了後に更新。 - extern タグ用シムの現状と撤去条件(hv1 inline 安定後に除去)を明記。 Acceptance(phase 20.45) - Hako PRIMARY(HAKO_PRIMARY_NO_FALLBACK=1)で代表構文が rc パリティ。 - Array/Map: push/size=2、set/size=1 の rc カナリが PRIMARY で PASS。 - Provider 複数ブロック代表(if-nested/else-if/if→match)が rc で緑維持。 Changes (recent) - nyash.toml に box_types/box_methods を追加(ArrayBox/MapBox の method_id を中央集約)。 - PluginHost.resolve_method が中央定義を参照(ライブラリ無しでも解決可)。 - test_runner: v1/hv1 と v0(newbox/boxcall) の振分けを追加(hv1 inline / Hako Core dispatcher)。 - MirBuilder RunnerMin: lower_return_int_box.hako の出力を MIR JSON v0 の正しい形(functions 配列 + name="main" + blocks.id)へ修正。 - これにより HAKO_PRIMARY_NO_FALLBACK=1 の canary(hako_primary_no_fallback_if_compare_core_exec_canary_vm)が緑化。 // Loop compares normalization (Step‑1) - Loop lowers(simple/count_param/sum_bc): Compare 受理を拡張し Lt 形へ正規化。 - i < L / i <= L は既存通り(<= は L+1)。 - L > i / L >= i は左右スワップで受理(>= は L+1)。 - i != L は init=0, step=1 の単純カウントに限り i < L と同値として受理。 - Canaries: phase2039 に追加(swapped > / >=, !=)し、Core verify で PASS を確認。 // Step‑2/3 generalization (count_param) - step 一般化: Int 2,3,… と Local Var 由来の step を受理。'-' は負の step に正規化(Add + 負値)。 - 降順対応: i > / i >= limit を cmp=Gt/Ge で build2 へ伝達。 - init/limit 起源の拡大: Local Var(Int)由来を逆引きで受理。 - Canaries: step=2 / step(Local) / 降順('-')/ limit(Local) / init(Local) を追加し PASS。 // Step‑4(部分) break/continue 検出の堅牢化(sum_bc) - 'i==X' に加え 'X==i' も受理。専用カナリー(swapped equals) PASS。 - If(var != X) else [Break] の最小サブセットを受理(loop_scan_box へ委譲)。専用カナリー PASS。 - If(var != Y) else [Continue] は検出実装あり(inline)が未検証→次段で helper へ移設しつつ canary 追加予定。 What’s green (20.34) - Loop/PHI unify (phi_core) in JSON v0 bridge — unified path used (toggle exposed). - Program(JSON v0) PHI‑trace canaries — PASS. - Core exec canaries (builder → emit → Core) — now routed and PASS: - mirbuilder_internal_core_exec_canary_vm (rc=10) - mirbuilder_internal_loop_core_exec_canary_vm (rc=3) - mirbuilder_internal_loop_count_param_core_exec_canary_vm (rc=6) - mirbuilder_internal_loop_sum_bc_core_exec_canary_vm (rc=8) Recent changes (summary) - Added MIR JSON v0 loader (minimal): src/runner/mir_json_v0.rs - Supports const/compare/branch/jump/phi/ret/copy - Promoted --mir-json-file to “execute + exit(rc)” - v1 → try_parse_v1_to_module; v0 → minimal loader; executes via Core interpreter - rc mapping unified in execute_mir_module_quiet_exit - verify_mir_rc improvements (tools/smokes/v2/lib/test_runner.sh) - Core primary: MIR(JSON) uses --mir-json-file, Program(JSON v0) uses --json-file - Mini‑VM(hakovm)rc==1 ヒューリスティックを削除し、経路評価を素直化(v1はCore、v0はhakovmに整流) - Hako JSON reader minor fix - lang/src/vm/core/json_v0_reader.hako: r# raw を通常文字列に統一(Hako生文字列の互換性向上) - MIR JSON v1 bridge extended - parse_const_value now handles f64/float, bool, string, and handle(StringBox) → ConstValue::String - Direct extern names supported in VM interpreter: env.mirbuilder.emit, env.codegen.emit_object - New v1 canaries (Core route) - tools/smokes/v2/profiles/quick/core/phase2035/v1_method_string_indexof_canary_vm.sh - tools/smokes/v2/profiles/quick/core/phase2035/v1_extern_mirbuilder_emit_canary_vm.sh - tools/smokes/v2/profiles/quick/core/phase2035/v1_method_string_substring_1arg_canary_vm.sh - tools/smokes/v2/profiles/quick/core/phase2035/v1_method_string_substring_2args_canary_vm.sh - tools/smokes/v2/profiles/quick/core/phase2035/v1_array_push_size_canary_vm.sh - (map) tools/smokes/v2/profiles/quick/core/phase2035/v1_map_set_get_size_canary_vm.sh - Note: returns size (1) for rc stability; get-path validated structurally - 20.38 extern bring-up (Hakorune primary) - Hakorune provider tags: prints `[extern/c-abi:mirbuilder.emit]` / `[extern/c-abi:codegen.emit_object]` when `HAKO_V1_EXTERN_PROVIDER_C_ABI=1`(既定OFF) - Core extern provider: when `HAKO_V1_EXTERN_PROVIDER=1`, `env.mirbuilder.emit` / `env.codegen.emit_object` return empty string (stub) to keep rc=0(verify fallbackの安定化) - Dispatcher(FLOW): minor cleanup to avoid stray scanning code; ret-path returns value and does not emit trailing prints - Canaries: phase2038 emit/codegen → PASS(タグ+rc=0 を固定)。phi 追加ケース(then→jump combo3)も PASS。 Open (pending) - SSOT helpers(binop_lower / loop_common)の導入と呼び出し置換(Builder/Bridge)。 - Continue ‘!=’ else の builder 経路の MIR 生成整流(rc=8 固定化)。 - P1〜P4 の実装・緑化(上記 Action Items)。 Active toggles (debug/verify) - HAKO_VERIFY_PRIMARY=hakovm|core(既定 hakovm、Coreは診断) - HAKO_V1_DISPATCHER_FLOW=1(v1 FLOW 実行) - HAKO_V1_EXTERN_PROVIDER=1(Hako extern provider 有効) - HAKO_V1_EXTERN_PROVIDER_C_ABI=1(タグ/ブリッジ実験。既定OFF) - HAKO_V1_PHI_STRICT=1 / HAKO_V1_PHI_TOLERATE_VOID=1(φポリシー) - NYASH_RESOLVE_TRACE=1 / NYASH_RESOLVE_NORMALIZE=1(resolver dev) How to run (quick) - Build: `cargo build --release` - Program v0 PHI‑trace (debug): - `SMOKES_ENABLE_DEBUG=1 bash tools/smokes/v2/profiles/quick/core/phase2034/program_v0_if_phi_trace_vm.sh` - `SMOKES_ENABLE_DEBUG=1 bash tools/smokes/v2/profiles/quick/core/phase2034/program_v0_loop_phi_trace_vm.sh` - Core exec canaries(20.34 緑対象): - `bash tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_internal_core_exec_canary_vm.sh` - `bash tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_internal_loop_core_exec_canary_vm.sh` - `bash tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_internal_loop_count_param_core_exec_canary_vm.sh` - `bash tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_internal_loop_sum_bc_core_exec_canary_vm.sh` Mini‑VM policy(20.34) - 実装は維持(alias/ret/phi 最小系を今後整える)。ただし quick の canary は Core へ寄せて緑化。 - 20.36 で verify primary を hakovm に段階的に切替、Mini‑VM green を進める。 Next (20.35 — scoped; behavior unchanged) 1) MIR JSON v1 loader expansion(Method/Extern/BoxCall — 最小) - callee.type=Method → BoxCall 復元(box_name/method/receiver/args) - callee.type=Extern → ExternCall 復元(env.get/env.codegen.emit_object/env.mirbuilder.emit/console.log など) - effects 未指定は PURE 既定、WRITE 系は最小でフラグ化(実害ゼロ) - v1 canary 追加(string indexOf/substring、array push/size、map set/get/size、extern env.get) 2) Using/alias の推移解決の堅牢化(深さ/循環/キャッシュ) - 実装済み(DFS 深さ上限=10、循環検知、キャッシュ)。strict では曖昧解決をエラー扱い。 3) ドキュメント:今回の経路(Core/verify)を roadmap に反映(DONE) Structure cleanups (20.35 A→B→C) - A) v1 mir_call 両対応(flat/nested): 実装済(ローダで互換吸収)。 - B) Extern provider 単一点化: 実装済(handlers/extern_provider.rs)。calls.rs/externals.rs から委譲。 - C) Const パース共通化: 実装済(src/runner/mir_json/common.rs)。まず v1 から採用(v0 は次段)。 Next (20.36 — verify primary → hakovm, preinclude removal, C‑ABI scaffold) - Verify primary 切替(段階): hakovm → Core fallback - preinclude 非推奨化(quick から撤去) - Mini‑VM の最小状態(len/size/push の簡易 state)を flag ガードで導入(デフォルトOFF)— 導入済 - 受信者別サイズ管理フラグ `HAKO_VM_MIRCALL_SIZESTATE_PER_RECV=1` を導入(canary 追加済) - HAKO_VM_MIRCALL_SIZESTATE=1 は緑化済(push 2回→size=2)。次は受信者別管理を flag で導入: HAKO_VM_MIRCALL_SIZESTATE_PER_RECV=1 - C‑ABI 設計(docs + ヘッダ雛形) Known open items(tracked to 20.36) - Mini‑VM: using/alias の推移解決(selfhost.vm.helpers.* 連鎖) - Mini‑VM: ret/phi の最小ケースで rc が確実に数値化されるよう整備(継続確認) Next (20.37 — v1 Dispatcher & Phi) 1) V1SchemaBox: get_function_ir(JSON→IR) を拡張(blocks/insts/phi_table を一括) 2) NyVmDispatcherV1Box: IR反復へ切替(スキャナ依存の最終撤去)、今は二重化(IR優先/scan後退互換) 3) Resolver/inline: AST prelude マージで推移usingを一次収束(Claude codeで進行)、ランナーは既存fallback維持 Next (Hotfix — Using/Prelude Unification) 1) vm.rs: using_ast 経路を `merge_prelude_text` に一本化(ASTマージ撤去) 2) vm.rs: Hako 構文検出で Hakorune VM へ切替(NyashParser をバイパス) 3) strip.rs: `.hako` の AST パース抑止と診断ガイド 4) verify: extern canary を PASS 化(末尾 rc 抽出の安定化) Docs: - docs/development/architecture/phi-entry-in-hako.md に φ entry 設計のSSOTを記載(不変条件/flags/テスト) Next (20.38 — extern provider & C‑ABI) 1) HakoruneExternProviderBox を拡張(warn/error/emit の最小タグ/空文字挙動)— 完了 2) HAKO_V1_EXTERN_PROVIDER=1 の canary 追加(構造緑固定)— 完了 3) C‑ABI 導線のPoC接続(emit/codegen、既定OFF)— 完了(タグ+rc=0) 4) hv1 inline 安定化(残): -c 経路の using resolver に modules.workspace を強制ロードするか、dispatcher の using を dev 限定で path 化。 5) include 撤去の計画(dev → 本線): - まず stub カナリーの include は撤去済み(rc=0 のみ確認)。 - hv1 inline カナリーの prelude include は暫定(dev専用)。-c/alias 安定後に alias へ移行して include を撤去する。 - ランナー側では merge_prelude_text を既定経路とし、include は quick=ERROR のポリシーを維持。 Roadmap links(per‑phase docs) - Index: docs/private/roadmap/README.md - Phase 20.34: docs/private/roadmap/phases/phase-20.34/README.md - Phase 20.35: docs/private/roadmap/phases/phase-20.35/README.md - Phase 20.36: docs/private/roadmap/phases/phase-20.36/README.md Appendix — Toggle quick reference - NYASH_MIR_UNIFY_LOOPFORM=1|0 … Loop/PHI 統一(既定ON) - HAKO_VERIFY_PRIMARY=hakovm|core … verify 実行経路(今は core 優先で緑化) - NYASH_VM_TRACE_PHI=1 … VM PHI 適用トレース - HAKO_PHI_VERIFY=1 | NYASH_PHI_VERIFY=1 … ビルダー側の PHI inputs 検証 - HAKO_VM_PHI_STRICT=0(互換:NYASH_VM_PHI_STRICT=0) … 実行時 PHI 厳格 OFF(開発時のみ) Updates (2025-11-04) - hv1 inline: alias-only route stabilized (no include/preinclude). vm.rs wrapper now uses `using selfhost.vm.hv1.dispatch` and relaxes fail-fast for child. - Verify harness: include+preinclude fallback for v1 removed in `verify_mir_rc`; alias-only hv1 is the standard path. - Concat-safety (hv1 scope): replaced `"" + ` coercions with `StringHelpers.int_to_str(...)` in `lang/src/vm/hakorune-vm/dispatcher_v1.hako` and `lang/src/vm/boxes/mir_call_v1_handler.hako`. # Handoff — 20.43 Kickoff (15h progress) Focus (next) - Start Phase 20.43: MIR generation coverage for call/method/newbox/load/store/typeop, with minimal Array/Map bridge (structure-first, no behavior change). What’s landed this session (DONE) - NewBox → Constructor (minimal lower) - Added: `lang/src/mir/builder/internal/lower_newbox_constructor_box.hako` - Wired in: `lang/src/mir/builder/MirBuilderBox.hako` (try_lower early) and alias in `nyash.toml`. - Direct canary (PASS): `tools/smokes/v2/profiles/quick/core/phase2043/lower_newbox_constructor_direct_core_exec_canary_vm.sh`. - Method(size) → structural MIR (Array) - Added: `lang/src/mir/builder/internal/lower_method_array_size_box.hako` + alias in `nyash.toml`. - Direct structural canary (PASS): `tools/smokes/v2/profiles/quick/core/phase2043/lower_method_array_size_direct_struct_canary_vm.sh`. - Method(push) → structural MIR (Array) - Added: `lang/src/mir/builder/internal/lower_method_array_push_box.hako` + alias in `nyash.toml`. - Direct structural canary (PASS): `tools/smokes/v2/profiles/quick/core/phase2043/lower_method_array_push_direct_struct_canary_vm.sh`. - New → Constructor (direct) and Method(size/push) canaries all green under phase‑2043. - Array get/set - Added: `lang/src/mir/builder/internal/lower_method_array_get_set_box.hako` + alias. - Direct structural canary (PASS): `tools/smokes/v2/profiles/quick/core/phase2043/lower_method_array_get_set_direct_struct_canary_vm.sh`. - Map size/get/set - Added: `lang/src/mir/builder/internal/lower_method_map_size_box.hako`, `lower_method_map_get_set_box.hako` + aliases. - Direct structural canaries (PASS): `lower_method_map_size_direct_struct_canary_vm.sh`, `lower_method_map_get_set_direct_struct_canary_vm.sh`. - Load/Store(最小) - Added: `lang/src/mir/builder/internal/lower_load_store_local_box.hako` + alias。 - Direct structural canary (PASS): `lower_load_store_local_direct_struct_canary_vm.sh`。 - TypeOp Check(最小) - Added: `lang/src/mir/builder/internal/lower_typeop_check_box.hako` + alias。 - Direct structural canary (PASS): `lower_typeop_check_direct_struct_canary_vm.sh`。 - TypeOp Cast(最小) - Added: `lang/src/mir/builder/internal/lower_typeop_cast_box.hako` + alias。 - Direct structural canary (PASS): `lower_typeop_cast_direct_struct_canary_vm.sh`。 - Builder internal route stabilized for simple New → Core via runner_min - Added: `lang/src/mir/builder/internal/runner_min_box.hako` + alias。 - `verify_program_via_builder_to_core` uses runner_min first, with markers + optional full MirBuilder fallback. - Harness improvements - Builder output extraction with markers `[MIR_OUT_BEGIN]/[MIR_OUT_END]` in `tools/smokes/v2/lib/test_runner.sh`. - Debug tails for stdout/stderr when `HAKO_MIR_BUILDER_DEBUG=1`. - Enabled using for inline runs: `NYASH_ENABLE_USING=1` / `HAKO_ENABLE_USING=1`. Open items / blockers - Builder (internal/delegate) inline route still unstable for JSON capture; `phase2043/program_new_array_delegate_struct_canary_vm.sh` fails (no JSON in stdout). - Plan: switch builder to write MIR to a temp file (FileBox) and let harness read it; or adopt provider route in 20.44 (`env.mirbuilder.emit`). - Remaining lowers for 20.43 not yet added: method(push/get/set/len), load/store (local), typeop(is/as) minimal; builder wiring after direct lowers pass. Next-up checklist (20.43) 1) MirBuilder wiring: 上記 direct lowers を `MirBuilderBox` から段階採用(Return系フォールバック前)→ 一部(Array/Map/LoadStore/TypeOp)採用済み。 2) New(Map) は Constructor lower で既に生成可能(direct PASS)。Builder経路へ採用。 3) TypeOp: `Cast` 採用済(構造lower→canary→配線)。 4) Builder route 安定化(internal):lower ラッパー側で MIR を `/tmp` に保存→ハーネスが読む(pipe 揺れを回避)。 5) Delegate route(20.44 に接続):`env.mirbuilder.emit` を provider 経由に切替(構造は共通)。 6) Delegate route (optional): use provider `env.mirbuilder.emit` (20.44 scope) to make canaries robust. How to run - All new phase 20.43 canaries: - `bash tools/smokes/v2/run.sh --profile quick --filter phase2043` - Single tests: - NewBox direct: `tools/smokes/v2/profiles/quick/core/phase2043/lower_newbox_constructor_direct_core_exec_canary_vm.sh` - Method(size) direct: `tools/smokes/v2/profiles/quick/core/phase2043/lower_method_array_size_direct_struct_canary_vm.sh` Toggles (dev) - Inline Hako: `HAKO_FAIL_FAST_ON_HAKO_IN_NYASH_VM=0 NYASH_ENABLE_USING=1 HAKO_ENABLE_USING=1` - Builder internal: `HAKO_MIR_BUILDER_INTERNAL=1` (and `HAKO_MIR_BUILDER_DEBUG=1` for tails) Pointers - New lowers: `lang/src/mir/builder/internal/lower_newbox_constructor_box.hako`, `lang/src/mir/builder/internal/lower_method_array_size_box.hako` - Wiring: `lang/src/mir/builder/MirBuilderBox.hako` (try_lower order) and `nyash.toml` aliases - Harness: `tools/smokes/v2/lib/test_runner.sh` (marker extraction / debug tails) ---