Files
hakorune/CURRENT_TASK.md
nyash-codex 2f07ab6a30 docs(phase25.4): Phase 25.4 ロードマップ・ドキュメント整備
📋 Phase 25.4 計画確定: NamingBox SSOT化 & CLI設定箱

 追加ドキュメント:
- docs/development/roadmap/phases/phase-25.4-naming-cli-cleanup/
  - README.md: Phase 25.4 全体計画
  - A. NamingBox SSOT化(完了)
  - B. Stage-1 CLI 設定箱(次フェーズ)
  - C. MIR ログ観測リスト(次フェーズ)

- docs/development/roadmap/phases/phase-21.7-normalization/README.md
  - Phase 21.7 との関連性追記

- docs/development/roadmap/phases/phase-25.1/stage1-usingresolver-loopform.md
  - Phase 25.1 完了記録更新

- CURRENT_TASK.md: タスク進捗更新
  - Phase 25.4-A 完了
  - Phase 25.4-B/C 準備完了
  - MIR Builder 型混乱バグ調査完了記録

🎯 Phase 25.4 戦略:
0. 共通方針
   - 既定挙動は変えない(Fail-Fast + テスト緑キープ)
   - 新規ロジックは「小さな箱」に閉じ込める
   - まずドキュメント・構造を揃えてからコード

A. NamingBox SSOT化  完了
   - static/global 名前決定を src/mir/naming.rs に一本化
   - Builder/VM で統一ルール使用

B. Stage-1 CLI 設定箱(次フェーズ)
   - env.get() を Stage1CliConfigBox に集約
   - mode/backend/source 等を Config として管理

C. MIR ログ観測リスト(次フェーズ)
   - __mir__.log の一覧化・分類
   - 将来の MirLogBox 化準備

📊 テスト確認コマンド:
- cargo test -q mir_static_box_naming --lib
- cargo test -q mir_stage1_cli_entry_ssa_smoke --lib
- tools/smokes/v2/run.sh --profile quick

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 09:02:30 +09:00

34 KiB
Raw Blame History

Current Task — Phase 21.8 / 25 / 25.1 / 25.2 / 25.4 Snapshot2025-11-18 時点)

このファイルは「今どこまで終わっていて、次に何をやるか」を 1000 行以内でざっくり把握するためのスナップショットだよ。
詳細な履歴やログは git log CURRENT_TASK.md からいつでも参照できるようにしておくね。


0. 現在地ざっくり

  • フェーズ軸:
    • 21.8: Numeric Core / Core-15 まわりの安定化(既に日常的には安定運用)。
    • 25.x: Stage0/Stage1/StageB / Selfhost ラインのブートストラップと LoopForm v2 / LoopSSA v2 まわりの整備。
    • 25.1 系: StageB / Stage1 / selfhost 向けに、Rust MIR / LoopForm v2 / LoopSSA v2 を段階的に整える長期ライン。
  • Rust 側:
    • LoopForm v2 + ControlForm + Conservative PHI は、代表テストStage1 UsingResolver / StageB 最小ループ)ではほぼ安定。
    • 静的メソッド呼び出し規約と continue 絡みの PHI は 25.1m までで根治済み。
  • .hako 側:
    • StageB コンパイラ本体 / LoopSSA v2 / BreakFinderBox / PhiInjectorBox はまだ部分実装。
    • JSON v0 / selfhost ルートは Rust 側の LoopForm v2 規約に追いつかせる必要がある。
  • StageB / FuncScanner ライン:
    • Phase 25.3 をクローズし、stageb_fib_program_defs_canary_vm.sh が緑(defsTestBox.fib/Main.main、fib.body.body[*] に Loop)。
    • StageB は block パーサ優先 + defs を Block 包みで構造化。次手: Stage1 UsingResolver ループの Region+next_i 揃え / Stage1 CLI program-json selfhost 準備。

1. 最近完了した重要タスク

1-0. Phase 25.3 — FuncScanner / StageB defs 安定化(完了)

目的

  • StageB / FuncScanner ラインで defs が欠落したり Loop が脱落する問題を塞ぎ、selfhost 側の canary を緑に戻す。

やったこと

  • StageBDriverBox.main:
    • main 本文を {…} で包んだ block パーサ優先で Program(JSON) に組み立て、defs には {"type":"Block","body":[…]} 形式で埋め込むよう整理。
    • Program パーサ fallback は HAKO_STAGEB_PROGRAM_PARSE_FALLBACK=1 の opt-in に封じ込めskip_ws 崩れを回避)。
  • StageBFuncScannerBox._scan_methods:
    • block パーサ優先に統一し、Program パーサは HAKO_STAGEB_FUNC_SCAN_PROG_FALLBACK=1 でのみ有効化。
    • defs パラメータに必ず me を足す従来挙動は維持TestBox/Main いずれも同型で出力)。
  • Rust 層の追加変更なしLoopForm v2 / LoopSnapshotMergeBox をそのまま利用)。

結果

  • tools/smokes/v2/profiles/quick/core/phase251/stageb_fib_program_defs_canary_vm.sh が安定して PASS。
    • Program.kind == "Program"
    • defsTestBox.fib / Main.main を保持していること。
    • TestBox.fib.body.body[*]Loop ノードが含まれること。 を満たした状態で rc=0 になることを確認。
  • FuncScanner / StageB 経由の fib defs ラインは LoopForm v2 + LoopSnapshotMergeBox 上で構造的に安定したとみなし、Phase 25.3 はクローズ。
  • 次フェーズの入口が整理できたので、Stage1 UsingResolver ループRegion+next_i 形)と Stage1 CLI program-json/selfhost 導線に着手可能。

1-1. Phase 25.1m — Static Method / LoopForm v2 continue + PHI Fix完了

目的

  • 静的メソッド呼び出し時の「暗黙レシーバ引数ずれ」バグと、LoopForm v2 経路における continue + header PHI の欠落を根本から直す。

Rust 側(静的メソッド / 暗黙レシーバ / JSON v0 Bridge

  • src/mir/function.rs::MirFunction::new
    • 暗黙 receiver 判定を是正し、「第 1 パラメータが Box 型の関数だけ」をインスタンスメソッド with receiver とみなす。
    • 非 Box 型(String, Integer など)で始まるパラメータ列の関数は、暗黙レシーバなしの静的メソッド / Global 関数として扱うように変更。
    • その結果:
      • static box TraceTest { method log(label) { ... } } に対して TraceTest.log("HELLO") を呼ぶと、 label"HELLO" が正しく入る(以前は label = null になっていた)。
    • src/mir/builder/decls.rs::build_static_main_box
      • Main.main(args) を「静的エントリ関数」に lower する経路を NYASH_BUILD_STATIC_MAIN_ENTRY=1 のときだけ有効 にし、 通常の VM 実行では wrapper main() を正規エントリとして扱うように整理。
      • これにより、「Main.main(args) 版ではループが 1 度も回らず return 0 で終わる」バグを解消。
    • JSON v0 Bridge 経由の Box メソッドStage1/StageB defs:
      • src/runner/json_v0_bridge/lowering.rsprog.defs の降下ロジックを調整し、
        • box_name != "Main" の関数定義をインスタンスメソッドとして扱って signature.params に「暗黙 me + 明示パラメータ」を載せる。
        • func_var_mapmefunc.params[0] を事前バインドし、残りのパラメータ名を params[1..] に対応づける。
      • これにより、Stage1UsingResolverFull._build_module_map() のように JSON では params: [] でも Hako 側で me._push_module_entry(...) を使う関数について、 Rust VM 実行時に me が未定義ValueId(0))になるケースを構造的に防止。

LoopForm v2continue + header PHI

  • src/mir/phi_core/loopform_builder.rs::LoopFormBuilder::seal_phis
    • シグネチャを seal_phis(ops, latch_id)seal_phis(ops, latch_id, &continue_snapshots) に拡張。
    • preheader と latch に加え、LoopBuilder 側で記録している continue_snapshots からの値も header PHI の入力 として統合。
    • pinned / carrier いずれも、header の全 predecessor:
      • (preheader, preheader_copy)
      • (continue_bb, value_at_continue)
      • (latch, value_at_latch) を入力として持つようになり、balanced scan など「continue を含むループ」の SSA が正しく構成される。
  • src/mir/loop_builder.rs::build_loop_with_loopform
    • let continue_snaps = self.continue_snapshots.clone();
    • loopform.seal_phis(self, actual_latch_id, &continue_snaps)?;
    • という形で、LoopBuilder → LoopForm 側に continue スナップショットを橋渡し。

ControlForm / LoopShape invariant

  • src/mir/control_form.rs::LoopShape::debug_validatedebug ビルドのみ)
    • 既存の:
      • preheader -> header エッジ必須
      • latch -> header バックエッジ必須
    • に加えて、次の invariant を追加:
      • continue_targets の各ブロックから header へのエッジが存在すること。
      • break_targets の各ブロックから exit へのエッジが存在すること。
    • これにより、LoopForm / LoopBuilder が continue / break 経路を誤配線した場合に、構造レベルで早期検知できる。

テスト / 検証

  • MIR ユニットテスト:
    • src/mir/phi_core/loopform_builder.rs::tests::test_seal_phis_includes_continue_snapshots
      • LoopFormBuilder 単体で「preheader + continue + latch」が PHI 入力に含まれることを固定。
    • src/tests/mir_stageb_loop_break_continue_verifies
      • StageB 風の loop + break/continue パターンで MirVerifier 緑。
    • src/tests/mir_stage1_using_resolver_verify.rs::mir_stage1_using_resolver_full_collect_entries_verifies
      • LoopForm v2/PHI v2 経路(現在は既定実装)で Stage1 UsingResolver フル版が MirVerifier 緑。
  • 実行観測:
    • 開発用 Hako loop_continue_fixed.hako:
      • 期待 RC=3 / 実測 RC=3、PHI pred mismatch なし。
    • StageB balanced scan:
      • StageBBodyExtractorBox のバランススキャンループに trace を入れて 228 回イテレーションが回ること、 ch == "{" ブランチで depth / i を更新 → continue → 次イテレーションに 確実に戻っている ことを確認。

1-2. Phase 25.1k — LoopSSA v2 (.hako) & StageB harness 追従Rust 側はおおむね完了)

目的

  • Rust 側の LoopForm v2 / ControlForm / Conservative PHI を SSOT としつつ、StageB / selfhost で使っている .hako 側 LoopSSA/BreakFinderBox/PhiInjectorBox をその規約に追従させる準備フェーズ。

Rust 側でやったこと(サマリ)

  • Receiver / pinning:
    • CallMaterializerBox::materialize_receiver_in_callee を事実上 no-op にし、 receiver の pinning / LocalSSA 連携を receiver::finalize_method_receiver に一本化。
    • MirBuilderpin_slot_names: HashMap<ValueId, String> を持たせ、 LocalSSA.ensure が「同じ slot にぶらさがる最新の ValueId」へ自動でリダイレクトできるようにした。
  • Compiler Box の分類:
    • CalleeResolverBox::classify_box_kindBreakFinderBox / PhiInjectorBox / LoopSSA を追加し、 Stage1/StageB 用 LoopSSA 箱を CalleeBoxKind::StaticCompiler として明示。

IfForm / empty else-branch の SSA fixStage1 UsingResolverFull 対応)

  • src/mir/builder/if_form.rs:
    • if cond { then }else なし)のパターンで、
      • else-entry 用に pre_if の variable_map から PHI ノードを生成したあと、
      • その PHI 適用後の variable_mapelse_var_map_end_opt=Some(...) として merge フェーズに渡すように修正。
    • 以前は empty else の場合に else_var_map_end_optNone になっており、 merge_modified_vars が pre_if の古い ValueId にフォールバックして、 merge ブロックで未定義の %0 などを参照するケースがあった(Stage1UsingResolverFull.main/0 の UndefinedValue
    • 修正後は then/else 両ブランチで「PHI 適用後の variable_map」が merge に渡されるため、 empty else でも header/merge の SSA が崩れない。
  • 検証:
    • src/tests/mir_stage1_using_resolver_verify.rs::mir_stage1_using_resolver_full_collect_entries_verifiesMirVerifier 緑になり、Stage1UsingResolverFull.main/0() の merge ブロックで PHI 後の値(例: %24)を正しく参照していることを MIR dump で確認済み。

.hako 側の今後25.1k 後半)

  • LoopSSA.stabilize_merges(json) を Rust LoopForm v2 の Carrier/Pinned 規約に合わせて実装する(現在はほぼ stub
  • StageB Test2tools/test_stageb_min.sh)で得られる Program(JSON v0) に対し、
    • Rust 側で NYASH_VM_VERIFY_MIR=1 を立てた実行結果と、
    • .hako 側 LoopSSA v2 適用後の JSON → Rust 実行結果 を比較し、BreakFinderBox / PhiInjectorBox / LoopSSA の責務を切り分けていく。

1-3. Phase 25.1e/f/g — LoopForm PHI v2 / ControlForm 統合(サマリ)

  • 25.1eLoopForm PHI v2 migration:
    • Local SSAlocal a = ...)の ValueId 分離を完了し、LoopForm v2 を「PHI/SSA の正」とする方向へ寄せた。
    • Stage1 UsingResolver / 基本的な StageB ループは、LoopForm v2 経路で MirVerifier 緑。
  • 25.1fControlForm 層の導入):
    • ControlForm / LoopShape / IfShape を導入し、Loop / If を共通ビューとして扱う箱を定義。
    • ここでは挙動を変えず、「構造だけを先に固定」する方針で設計を固めた。
  • 25.1gConservative PHI ↔ ControlForm ブリッジ):
    • phi_core::loopform_builder::build_exit_phis_for_control など、ControlForm から Conservative PHI を呼び出す薄いラッパを追加。
    • 既存の PHI ロジックはそのままに、将来の置き換えポイントだけを明示している。

1-4. Phase 25.1A3 — Stage1 CLI bridgestub 実装)

  • Rust 側: src/runner/stage1_bridge.rsrun_refactored 入口に組み込み、NYASH_USE_STAGE1_CLI=1 かつ再入ガードなしのときに lang/src/runner/stage1_cli.hako を子プロセスで起動する。STAGE1_EMIT_PROGRAM_JSON / STAGE1_EMIT_MIR_JSON / STAGE1_BACKEND / STAGE1_PROGRAM_JSON で mode 選択。entry override は STAGE1_CLI_ENTRY / HAKORUNE_STAGE1_ENTRY
  • .hako 側: Stage1Cli に最低限の本体を実装。
    • emit_program_json: Stage1 UsingResolver で prefix を結合し、BuildBox.emit_program_json_v0 で Program(JSON v0) を返す。
    • emit_mir_json: MirBuilderBox.emit_from_program_json_v0 をそのまま呼ぶdelegate 未設定なら null
    • run_program_json: backend==llvm の場合は env.codegen.emit_object まで通す。vm/pyvm は当面 MIR(JSON) を stdout に出すのみ(実行は Stage0 橋渡し未配線)。
    • CLI: emit program-json|mir-json / run --backend ... <src> を受理。NYASH_SCRIPT_ARGS_JSON を JSON で best-effort 伝播。
  • Docs: docs/development/roadmap/phases/phase-25.1/stage1-usingresolver-loopform.md に stub 状態を追記run は暫定挙動)。
  • Known gaps: vm/pyvm 実行はまだ Stage0 への橋渡し未着手。llvm も emit object 止まりlink/exec は後続)。

1-5. Phase 25.1A4 — Using SSOT 薄設計BuildBox include 除去

  • SSOT: lang/src/using/resolve_ssot_box.hako に README 相当のコメントと I/Fresolve_modules/resolve_prefixを追加。現状は no-op だが「using をここで扱う」窓口を固定。
  • Stage1UsingResolver: resolve_for_program_json を追加し、SSOT を呼ぶ導線だけ確保(現状は透過返し)。
  • BuildBox: 先頭の include を削除し、using lang.compiler.entry.bundle_resolver as BundleResolver に置換StageB パーサが include を解せない問題の足場づくり)。
  • 実行確認: NYASH_ALLOW_NYASH=1 HAKO_ALLOW_NYASH=1 NYASH_USE_STAGE1_CLI=1 STAGE1_EMIT_PROGRAM_JSON=1 ... cargo run --bin hakorune -- basic_test.hako が RC=0 で完走(ただし stdout は RC: 0 のみ、program-json 出力は未配線)。cargo run ... emit program-json は Rust CLI 側の表面が未対応のためエラー(想定挙動)。

2. まだ残っている問題・課題2025-11-18 時点)

2-1. StageB 本体の型エラー(String > Integer(13)

  • 症状:
    • StageB の Main.main 実行時に、 Type error: unsupported compare Gt on String(...) and Integer(13) が発生。
    • LoopForm v2 / PHI / continue 修正とは 独立の StageB 固有のロジック問題
  • 想定される原因:
    • StageB 側の body 構築 / JSON 生成で、本来数値比較にすべき箇所で「生の文字列」と整数を比較している。
    • もしくは、Parser/Scanner が len やインデックスを文字列のまま扱っている部分がある。
  • 対応方針(次フェーズ向けメモ):
    • StageBBodyExtractorBox.build_body_src が吐く body_src を最小ケースで抽出し、 その中から問題の比較式(>)がどのように生成されているかを特定する。
    • StageB の box レベルで:
      • 「どのフェーズで型を決めるか」(例: ParserBox / StageB / VM 手前)を決めてから修正する。
    • このタスクは 25.1c 続き or 新フェーズ25.1n 相当として、StageB 箱の設計側で扱う。

2-2. StageB 再入ガード env.set/2 の扱い

  • 現状:
    • 一部 StageB コードが env.set/2 を使った再入ガードに依存しており、 Rust VM 側には env.set/2 extern が定義されていないため、 ❌ VM error: Invalid instruction: extern function: Unknown: env.set/2 が発生するケースがある。
  • 方針メモ:
    • 選択肢 A: StageB 再入ガードを Box 内 stateフィールドに寄せて、env.set/2 依存をなくす。
    • 選択肢 B: StageB ハーネス専用に、最小限の env.set/2 extern を Rust 側に実装する(本番経路では使わない)。
    • 25.1m では構造修正Loop/PHI/receiverを優先し、この extern の話は据え置き。

2-3. .hako 側 LoopSSA v2Rust LoopForm v2 との乖離)

  • 現状:
    • lang/src/compiler/builder/ssa/loopssa.hakostabilize_merges() はまだ実質的に stub に近い。
    • StageB Test2compiler_stageb.hako 経由では、Rust MIR 側で LoopForm v2 / PHI v2 が安定した後も、 .hako 側 LoopSSA 経由の JSON から生成した MIR で PHI/SSA 問題が残る可能性がある。
  • 目標:
    • Rust LoopForm v2 を「制御構造と PHI の SSOT」とみなし、 .hako 側 LoopSSA が同じ Carrier/Pinned / preheader/header/exit の規約を JSON レベルで再現する。
  • やること(フェーズ 25.1k 後半〜 25.1f/g 連携):
    • 特定の関数(例: BreakFinderBox._find_loops/2を対象に、Rust 側 / .hako 側のそれぞれで生成されるループ構造を比較。
    • LoopSSA v2 の中に:
      • Carrier 変数の検出、
      • pinned 変数の扱い、
      • exit PHI の構築 を Rust LoopForm v2 に合わせて実装。
    • 2025-11-19 追記:
      • BreakFinderBox._find_loops/2 については、まず .hako 側を「region box」的に整理した。
        • header_pos / header_id / exit_pos / exit_id まわりの異常系を continue ではなく next_i ローカルへの代入で表現し、1 イテレーションの末尾で i = next_i に合流させる形に変更。
        • これにより、LoopForm v2 / LoopSSA 側から見ると「単一 region 内での分岐+最後に合流」という構造になり、 carrier/pinned 検出や今後の SSA 解析が行いやすくなった(挙動は従来と同じ)。

2-5. static box / me セマンティクス(観測タスクへ移行)

  • 現状:
    • static box StringHelpers のようなユーティリティ箱で、me.starts_with(src, i, kw) のように 同一箱内のヘルパー(starts_with)を me. 経由で呼んでいたため、Stage3 降下時に引数ずれが発生していた。
    • 具体的には、StringHelpers.starts_with_kw/3StringHelpers.starts_with/3 の降下で 実際の呼び出しが starts_with("StringHelpers", src, i, kw) のような 4 引数形になり、 starts_with(src, i, pat) 側では src="StringHelpers" / i=<ソース全文> となって、 if i + m > nString > Integer(13) 比較に化けていた。
  • 対応(完了済み・局所修正):
    • lang/src/shared/common/string_helpers.hakostarts_with_kw を、 if me.starts_with(src, i, kw) == 0 から if starts_with(src, i, kw) == 0 に書き換え、 static box ユーティリティに対する me 依存を除去した。
    • これにより、starts_with 内でのガード比較 i + m > n はすべて整数同士となり、 StageB fib ケースで発生していた String("...") > Integer(13) の TypeError は解消済み。
  • 今後Phase 25.1p 以降):
    • static box 全般における me セマンティクス(本当に「シングルトンインスタンス」として扱う箱と、 純粋な名前空間箱をどう区別するかは、25.1p の DebugLog フェーズで観測しながら設計を詰める。
    • 実際に Rust 層(build_me_expression / lower_static_method_as_function / FunctionDefBuilder::is_instance_method)を 統一規約に寄せる作業は、25.1p 以降のサブタスクとして扱う(現時点では局所修正でバグのみ解消)。

2-4. Builder / Selfhost まわりの残タスク(超ざっくり)

  • Builder 内部ルート20.43 系):
    • MirBuilderBox 経由の internal ルートで、MIR を stdout 経由ではなく一時ファイル / FileBox に書き出し、 ハーネスがそこから読む形に揃える案が残タスク。
  • Selfhost CLI / Stage1 CLI:
    • StageB / Stage1 CLI を「Rust VM / LLVM / PyVM / selfhost」の 4 経路で安定確認するラインは進行中。
    • 25.1m では Rust VM + StageB balanced scan を優先し、CLI 全体は次のフェーズで詰める。

3. 次にやること(候補タスク)

ここから先は「どのフェーズを進めるか」をそのときの優先度で選ぶ感じだよ。
Rust 側は LoopForm v2 / StageB fib / Stage1 UsingResolver 構造テストまで一通り整ったので、当面は Stage1 CLI / selfhost ラインの小さな箱から進める。

A. Stage1 CLI / Stage0 ブリッジPhase 25.1 — いまここ)

  • A1: Stage1 CLI stub を Stage0 Rust ランナーから呼び出すブリッジDONE
    • 実装: src/runner/stage1_bridge.rs src/runner/mod.rsmaybe_run_stage1_cli_stub を追加。
      • NYASH_USE_STAGE1_CLI=1(既定 OFFかつ NYASH_STAGE1_CLI_CHILD!=1 のときにだけ有効。
      • entry .hakoSTAGE1_CLI_ENTRY / HAKORUNE_STAGE1_ENTRY で上書き可能(既定: lang/src/runner/stage1_cli.hako)。
      • 入力ファイル / モード:
        • STAGE1_EMIT_PROGRAM_JSON=1: hakorune emit program-json <source.hako> を子プロセスで実行。
        • STAGE1_EMIT_MIR_JSON=1: STAGE1_PROGRAM_JSON があれば --from-program-json、なければ <source.hako> から emit mir-json
        • 上記どちらも無い場合: hakorune run --backend <backend> <source.hako>backend は STAGE1_BACKEND か CLI の backend 設定)。
      • NYASH_SCRIPT_ARGS_JSON を拾って -- 以降の script 引数も Stage1 側に転送。
      • 再入防止として子プロセスには NYASH_STAGE1_CLI_CHILD=1 を付与(子側からは Rust ブリッジを素通り)。
  • A2: Stage1 CLI skeleton の責務を doc に固定DONE
    • lang/src/runner/stage1_cli.hakoStage1Cli.emit_program_json/emit_mir_json/run_program_json/stage1_main のシグネチャとトグルトポロジーを固定。
    • docs/development/roadmap/phases/phase-25.1/stage1-usingresolver-loopform.md に Rust 側ブリッジの振る舞いとトグル名(NYASH_USE_STAGE1_CLI / STAGE1_EMIT_* / STAGE1_BACKEND / NYASH_STAGE1_CLI_CHILD)を追記。
  • A3: 次ステップ(未着手)
    • Stage1 CLI skeleton に StageB/BuildBox/MirBuilder 呼び出しを順に実装し、「Program(JSON)/MIR(JSON) を selfhost 経由で emit できる」状態まで持っていく。
    • tools/selfhost/run_stage1_cli.sh から呼び出す selfhost パスと、Rust CLl からのブリッジパスの両方で JSON I/O 契約が同じになるように揃える。

B. Stage1 UsingResolver / LoopForm v2 ラインPhase 25.1e 系フォロー)

  • B1: entry UsingResolver の Region+next_i 化とコメント整備(おおむね DONE
    • lang/src/compiler/entry/using_resolver_box.hako の 3 ループentries / JSON スキャン / modules_listは Region+next_i 形に揃え済み。
    • 役割コメント: resolve_for_sourceStageB body_src を受けて prefix を返す)、_collect_using_entriesJSON スキャンして entries を集める)、_build_module_mapmodules_list を map 化)を明記済み。
    • HAKO_STAGEB_APPLY_USINGS=0 の時は prefix を空 string にしつつ、depth ガードだけは走らせる仕様もコメントで固定。
  • B2: UsingResolver 構造テスト(ループ形/PHIの拡充DONE
    • src/tests/mir_stage1_using_resolver_verify.rs に Region+next_i ループと early-exit JSON スキャンパターンの軽量テストを追加。
    • これらは cargo test 経路で常時緑を維持し、v2 quick スモークへの昇格は「実行時間とイズを見ながら後続フェーズで検討」という扱いにするdocs にメモ済み)。
  • B3: pipeline_v2 UsingResolver との責務境界DONE
    • lang/src/compiler/pipeline_v2/using_resolver_box.hako 冒頭に、「entry 側=ファイル I/O + using 収集」「pipeline_v2 側=modules_json 上の alias/path 解決」と役割メモを追加。
    • RegexFlow ベースの単一路ループは Region 化不要stateful helperとし、LoopForm v2 の観点からも「観測対象外」とする。

C. StageB / LoopSSA / Selfhost まわり(中期タスク)

  • C1: StageB 再入ガード env.set/2 の整理(据え置き)
    • dev 専用 extern を Rust 側に追加するか、StageB 箱側で state に寄せるかを決める必要があるが、現在はループ/PHI ラインを優先し保留。
    • このタスクに着手するときは「prod/CI 経路から完全に切り離した dev ガード」として設計する。
  • C2: .hako LoopSSA v2 実装Rust LoopForm v2 への追従)
    • Rust LoopForm v2 の Carrier/Pinned/BodyLocalInOut モデルを .hako の LoopSSA に輸入し、StageB Test2 / selfhost CLI でも MirVerifier 緑を目指す中〜長期タスク。
    • 具体的な対象: lang/src/compiler/builder/ssa/loopssa.hako と StageB/BreakFinder 周辺の region 化済みループ。
  • C3: Selfhost / CLI 周辺のテスト整理
    • 代表的な selfhost / StageB / Stage1 CLI ケースを tests/tools 側でタグ付けquick/integration/selfhost、Phase 25.1 の「どこまでが Rust 側」「どこからが Stage1 側」を見える化する。

4. 履歴の見方メモ

  • 以前の CURRENT_TASK.md は ~1900 行の長いログだったけど、読みやすさ重視でこのファイルはスナップショット形式にしたよ。
  • 過去の詳細ログが必要になったら:
    • git log -p CURRENT_TASK.md
    • あるいは特定のコミット時点の CURRENT_TASK.mdgit show <commit>:CURRENT_TASK.md
      でいつでも復元できるよ。

Phase 25.4 — Naming & Stage1 CLI Cleanupdesign only

  • ねらい:
    • static box / global 呼び出しの命名規約を NamingBox に集約し、VM 側のレガシーフォールバック経路を撤去する。
    • Stage1 CLI の env/トグル解釈を 1 箇所の設定箱にまとめ、stage1_main の責務を薄く保つ。
    • __mir__.log ベースの MIR ログ観測ポイントをドキュメントで一覧化し、将来の正式 API 化に備える。
  • 現状:
    • NamingBoxsrc/mir/naming.rsは導入済みで、Builder 側の static メソッド名は encode_static_method 経由、VM 側の global 呼び出しは normalize_static_global_name 経由になっている。
    • VM 側の「canonical 名で見つからなければ元名でもう一度探す」フォールバックは削除済みで、mir_static_box_naming テスト群が Main._nop/0 経路を固定している。
    • Stage1 CLI は env-only 仕様argv 依存なし)で Stage0 ブリッジと接続済みだが、env 群の解釈はまだ stage1_main 内に散在している。
  • このフェーズでやること(設計レベル):
    • NamingBox を「static 名に触るすべてのコードの SSOT」として整理直接 format!("Box.main") する箇所を洗い出し)。
    • Stage1CliConfigBoxを設計し、env→Config 変換の責務とフィールドを docs に書き出す(実装は後続でも可)。
    • __mir__.log のタグと用途を 1 ページの docs にまとめ、dev 用ログと残したい観測ログを分けておく。

以上が 2025-11-18 時点の Phase 21.8 / 25 / 25.1 / 25.2 / 25.4 ラインの「いまどこ」「なに済み」「なに残り」だよ。
次にどの箱から攻めるか決めたら、ここに箇条書きで足していこうね。

3. これからやるタスクのラフ一覧25.1 / Stage1 系)

ここから先は「まず設計と箱分割を書いてから実装」という方針で進めるタスク群だよ。

A. Rust 層解析LoopForm v2 / JSON v0 / Stage1 観測)

  • A-1: LoopForm v2 / LoopSnapshotMerge の入口確認
    • src/mir/loop_builder.rs / src/mir/phi_core/loopform_builder.rs / src/mir/phi_core/loop_snapshot_merge.rs を「Stage1 から見た導線」として読み直し、どのレイヤで Carrier / Pinned / BodyLocalInOut が決まるかを short メモ化する。
  • A-2: JSON v0 → MIR ブリッジの導線整理
    • src/runner/json_v0_bridge/lowering/(特に loop_.rsを通して、Program(JSON v0).body / defs.body(Block) が LoopForm v2 までどう運ばれるかを図として docs に落とす。
  • A-3: Stage1 UsingResolver の MIR 観測
    • 既存テスト src/tests/mir_stage1_using_resolver_verify.rs の MIR dump を元に、「どのループが Region+next_i 化候補か」「既に問題なく LoopForm に乗っている場所はどこか」を箇条書きで整理する。

B. Stage1 UsingResolver 箱化・ループ整理(.hako 側)

  • B-1: Stage1UsingResolverBox の責務分割設計
    • lang/src/compiler/entry/using_resolver_box.hako を、collect_entries / modules_map / file_read などの小さいロジック箱に概念的に分割し、「どの箱が何を責務とするか」を docs に書く(実際のファイル分割は後段)。
  • B-2: すべてのループを Region+next_i 形に揃える計画
    • entry の UsingResolver 内に残っている「pos++/continue 多発型」ループを洗い出し、Region+next_i 形にどう書き換えるかを phase-25.1 docs に追記する。
    • 目的: LoopForm v2 / PHI から見たときに「1 region / 1 backedge / 明確な次位置決定」という形に統一する。
    • 状況メモ: entry 側 3 ループentries/JSON scan/modules_listは Region+next_i 化済み。残りなし。
  • B-3: pipeline_v2 UsingResolver との役割分担
    • lang/src/compiler/pipeline_v2/using_resolver_box.hako と entry/Stage1UsingResolverBox のどちらが「テキスト / JSON / modules_map」のどこまでを担当するかを整理し、責務境界をドキュメントに固定する。
    • 状況メモ: pipeline_v2 側は modules_json の alias 解決のみRegexFlow.find_from の単一路ループ。Region 化不要として据え置き、境界だけ明記。
  • B-4: 構造テストの追加計画
    • Region+next_i パターンの軽量 SSA テスト(すでに 1 本追加済み)を基準に、もう 1〜2 本、UsingResolver ソースに近いパターンJSON スキャンearly-exitを追加する方針を決める。

C. Stage1 CLI / program-json / mir-json SelfHost 準備

  • C-1: Stage1 CLI インターフェースの設計メモ
    • .hako → Program(JSON) / Program(JSON) → MIR(JSON) / MIR(JSON) → 実行 を Stage1 側からどう呼び出すか(関数名・引数レベル)を docs に先に書く。
  • C-2: StageB → Stage1 データフロー図
    • compiler_stageb.hako → Program(JSON v0) → Stage1 UsingResolver → MirBuilder までのパイプラインを Phase25.1 ドキュメントに 1 枚の図としてまとめる。
  • C-3: Rust CLI 側ブリッジの最小ガード案
    • Stage0/Rust CLI は「Program(JSON/MIR(JSON) を受け取り VM/LLVM に流すだけ」に縮退させる方針と、既定 OFF トグルselfhost 入口)をどう切るかを設計メモとして追加。

D. 将来フェーズ向けメモvariable_map 決定化ライン)

  • D-1: MirBuilder::variable_map / BoxCompilationContext::variable_map BTreeMap 化案
    • どの構造を HashMap→BTreeMap 化するか、どのテスト(mir_funcscanner_skip_ws_vm_debug_flaky など)で決定性を確認するかを Phase25.x の設計メモとして書いておく。
  • D-2: dev 専用 / flaky テストの扱い方針
    • どのテストが dev ignore手動実行用で、いつ/何を満たしたら常時有効に戻すかを、このファイルと関連 README に明確に残す。

このセクションは「すぐ実装する TODO ではなく、25.1〜25.x ラインで踏むべき設計タスク一覧」として使う予定だよ。
(静的 me-call 修正の参考メモはここに残しつつ、別セクションは整理済み)

3. Phase 25.1q — LoopForm Front UnificationDONE / follow-up 別タスクへ)

  • 目的: Rust AST ルート (LoopBuilder) と JSON v0 ルート (json_v0_bridge::lower_loop_stmt) のループ lowering を “LoopFormBuilder + LoopSnapshotMergeBox” に一本化し、どの経路からでも同じ SSOT を見るだけで良い構造に揃える。
  • 完了状態:
    • AST ルート:
      • LoopBuilder::build_loop_with_loopform で canonical continue_merge_bb を常時生成し、continue_target を header ではなく continue_merge_bb に統一済み。
      • LoopFormBuilder::seal_phis / LoopSnapshotMergeBox の continue/exit 入力は「preheader + continue_merge + latch」「header + break snapshots」で完全管理。
    • JSON v0 ルート:
      • loop_.rsLoopFormJsonOps を実装し、preheader/header/body/latch/continue_merge/exit の block ID を AST ルートと同じ形で生成。
      • break/continue/exit の snapshot を LoopSnapshotMergeBox でマージし、canonical continue_merge → header backedge を JSON 側でも採用。
      • tests/json_program_loop.rs で JSON v0 だけを入力にした軽量ループ(通常 / continue / body-local exitMirVerifier で確認するスモークを追加。
    • Docs/README:
      • docs/development/roadmap/phases/phase-25.1q/README.md に「AST/JSON ともに LoopForm v2 + LoopSnapshotMergeBox が SSOT」と明記。
      • src/runner/json_v0_bridge/README.md で “bridge は薄いアダプタであり、新しい PHI 仕様は loopform 側でのみ扱う” とガードを追記。
      • src/mir/phi_core/loop_phi.rs には “legacy分析用のみ” コメントを追加。将来の cleanup (Phase 31.x) で削除対象とする。
  • 残タスクは別フェーズへ:
    • Stage1 UsingResolver 周りの SSA バグ(tests::mir_stage1_using_resolver_verify::mir_stage1_using_resolver_full_collect_entries_verifies の Undefined Valueは 25.1q の範囲外。LoopForm の SSOT 化は終わっているため、今後は Stage1 側の PHI/Env スナップショット設計タスクとして切り出す。
    • JSON v0 → Nyash AST への統合案や loop_phi.rs の実ファイル削除は、Phase 31.x cleanup 計画側で扱う。