Files
hakorune/docs/development/current/main/10-Now.md
tomoaki af2a5e27d6
Some checks failed
fast-smoke / fast (push) Has been cancelled
feat(normalization): Phase 142 P1 - LLVM EXE parity for loop normalization
Phase 142-loopstmt P1: LLVM EXE smoke test for statement-level loop normalization

- Added: tools/smokes/v2/profiles/integration/apps/phase142_loop_stmt_only_then_return_length_min_llvm_exe.sh
- Verification: Exit code 3 parity with VM test
- Status:  PASS (exit code 3, string length computed correctly)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 05:42:11 +09:00

796 lines
43 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Self Current Task — Now (main)
## Next (planned)
- Phase 141 P2+: Call/MethodCall 対応effects + typing を分離して段階投入)
- Phase 143-loopvocab: StepTree の語彙拡張loop 内 if/break/continue を「新パターン追加」ではなく「語彙追加」で吸収)
- 詳細: `docs/development/current/main/30-Backlog.md`
## 2025-12-19Phase 142-loopstmt P0 完了 ✅
**Phase 142-loopstmt P0: Statement-Level Loop Normalization**
- 目的: 正規化単位を "block suffix" から "statement (loop 1個)" へ寄せてパターン爆発を防ぐ
- 変更:
- PlanBox: loop(true) に対して常に loop_only() を返すconsumed=1
- SuffixRouter: LoopOnly を受け入れて実行
- build_block: consumed 後も後続文を処理break 削除)
- 実装 SSOT:
- `src/mir/builder/control_flow/normalization/plan_box.rs`
- `src/mir/builder/control_flow/joinir/patterns/policies/normalized_shadow_suffix_router_box.rs`
- `src/mir/builder/stmts.rs`
- Refactoring:
- LoopWithPost variant を deprecated4 commits
- suffix_router コメント更新
- README 更新
- Tests:
- Fixture: `apps/tests/phase142_loop_stmt_only_then_return_length_min.hako`exit code 3
- VM smoke: ✅ PASS
- Unit tests: ✅ 10/10 passed
- Regression: ✅ Phase 131, 141 green
- 統計: -38 lines net (code reduction success!)
- 入口: `docs/development/current/main/phases/phase-142-loopstmt/README.md`
⚠️ **Note**: Phase 142 (Canonicalizer Pattern Extension) とは別物。SSOT 衝突回避のため phase-142-loopstmt として独立管理。
## 2025-12-19Phase 141 P1.5 完了 ✅
**Phase 141 P1.5: KnownIntrinsic registry + available_inputs 3-source merge + diagnostics**
- 目的: “既知 intrinsic だけ” を SSOT 化しつつ、suffix 正規化が prefix の変数を見失わないようにする(既定挙動不変)。
- Task Bバグ修正: `AvailableInputsCollectorBox::collect(.., prefix_variables)` を追加し、Function params > Prefix variables > CapturedEnv の 3-source merge に変更
- Task ASSOT化: `KnownIntrinsicRegistryBox` を追加し、intrinsic の metadataname/arity/type_hint`known_intrinsics.rs` に集約
- Task C診断: `OutOfScopeReason::IntrinsicNotWhitelisted` を追加し、Call/MethodCall の out-of-scope 理由を精密化
- 実装 SSOT:
- `src/mir/control_tree/normalized_shadow/available_inputs_collector.rs`
- `src/mir/control_tree/normalized_shadow/common/known_intrinsics.rs`
- `src/mir/control_tree/normalized_shadow/common/expr_lowerer_box.rs`
- `src/mir/control_tree/normalized_shadow/common/expr_lowering_contract.rs`
- `src/mir/builder/control_flow/normalization/execute_box.rs`
- 設計 SSOT:
- `docs/development/current/main/design/normalized-expr-lowering.md`
## 2025-12-19Phase 141 P1 完了 ✅
**Phase 141 P1: KnownIntrinsicOnly (length0)**
- 目的: impure 導入の安全なオンランプとして、既知 intrinsic小さな allowlistのみを ExprLowerer に追加
- 仕様:
- `ExprLoweringScope::WithImpure(ImpurePolicy::KnownIntrinsicOnly)` でのみ `receiver.length()` を lowering
- それ以外の Call/MethodCall は引き続き `Ok(None)`(既定挙動不変)
- Fixture:
- `apps/tests/phase141_p1_if_only_post_k_return_length_min.hako`expected exit code 3
- Smoke tests:
- VM: `tools/smokes/v2/profiles/integration/apps/phase141_p1_if_only_post_k_return_length_vm.sh`
- LLVM EXE: `tools/smokes/v2/profiles/integration/apps/phase141_p1_if_only_post_k_return_length_llvm_exe.sh`
- 入口: `docs/development/current/main/phases/phase-141/README.md`
## 2025-12-19Phase 141 P0 完了 ✅
**Phase 141 P0: Impure Extension Contract (Call/MethodCall stays out-of-scope)**
- 目的: 次フェーズの Call/MethodCall 導入に向けて、pure/impure 境界の contractSSOTを型で固定
- SSOT:
- `src/mir/control_tree/normalized_shadow/common/expr_lowering_contract.rs`
- `src/mir/control_tree/normalized_shadow/common/expr_lowerer_box.rs`
- 仕様: Call/MethodCall は引き続き `Ok(None)`(既定挙動不変)
- 入口: `docs/development/current/main/phases/phase-141/README.md`
## 2025-12-19Phase 140 完了 ✅
**Phase 140: NormalizedExprLowererBox (pure expressions)**
- 目的: “return の形追加” をやめて、pure expression を AST walker で一般化して収束させる
- SSOT:
- `src/mir/control_tree/normalized_shadow/common/expr_lowerer_box.rs`
- `src/mir/control_tree/normalized_shadow/common/return_value_lowerer_box.rs`
- 仕様:
- pure のみVariable / Integer&Bool literal / unary(not,-) / arith(+,-,*,/) / compare(==,!=,<,<=,>,>=)
- Call/MethodCall など impure は `Ok(None)`Phase 141+
- 入口: `docs/development/current/main/phases/phase-140/README.md`
## 2025-12-19Phase 139 完了 ✅
**Phase 139: post-if `post_k` Return Lowering Unification**
- 目的: if-only `post_k` 側の return lowering を `ReturnValueLowererBox` に統一し、loop/if の出口を一本化
- 実装:
- `src/mir/control_tree/normalized_shadow/post_if_post_k.rs` の return lowering を `ReturnValueLowererBox::lower_to_value_id()` に委譲
- out-of-scope は `Ok(None)` でフォールバック既定挙動不変・dev-only
- Fixture:
- `apps/tests/phase139_if_only_post_k_return_add_min.hako`expected exit code 4
- Smoke tests:
- VM: `tools/smokes/v2/profiles/integration/apps/phase139_if_only_post_k_return_add_vm.sh`
- LLVM EXE: `tools/smokes/v2/profiles/integration/apps/phase139_if_only_post_k_return_add_llvm_exe.sh`
- 入口: `docs/development/current/main/phases/phase-139/README.md`
## 2025-12-18Phase 138 完了 ✅
**Phase 138: ReturnValueLowererBox - Return Lowering SSOT**
- 目的: Return lowering logic を共有 Box として抽出し SSOT を確立
- 実装:
- Created `common/return_value_lowerer_box.rs` (~300 lines)
- Migrated `loop_true_break_once.rs` to use Box (2 call sites)
- 5 comprehensive unit tests for all patterns
- Code reduction: ~115 lines removed from loop_true_break_once.rs
- SSOT:
- `ReturnValueLowererBox::lower_to_value_id()`
- Supported: Variable, Integer literal, Add expression (x + 2, 5 + 3)
- Fallback: Out-of-scope patterns return `Ok(None)`
- Tests:
- 5 new unit tests: variable, integer literal, add (var+int), add (int+int), fallback (subtract)
- All regressions PASS: Phase 137/97/131/135/136
- Design Decision:
- Phase 138 P0 migrated loop paths only
- Phase 139 P0 will unify post_if_post_k.rs for complete SSOT
- Architecture Impact:
- Single location for return lowering improvements
- Isolated unit tests for return lowering logic
- Easy to add new return patterns in one location
- 入口: `docs/development/current/main/phases/phase-138/README.md`
---
## 2025-12-18Phase 137 完了 ✅
**Phase 137: loop(true) break-once with return add expression**
- 目的: Phase 136 を拡張し、return 時に最小 add 式をサポート
- 仕様:
- `return x + 2`variable + integer literal→ exit code 3
- `return 5 + 3`integer literal + integer literal→ exit code 8
- `loop(true) { x = 1; break }; x = x + 10; return x + 2` → exit code 13
- 実装:
- `src/mir/control_tree/normalized_shadow/loop_true_break_once.rs``lower_return_value_to_vid()` 行 638-743, BinaryOp Add at 行 673
- BinaryOp Add パターン追加LHS: Variable or Integer literal, RHS: Integer literal only
- Ok(None) fallback for out-of-scope patterns`return x + y`, `return x - 2` 等)
- Return Value Lowering SSOT:
- Documentation: `loop_true_break_once.rs`(行 29-46, module-level comment
- Boxification trigger: 2+ files で同一 return lowering logic が必要になった時
- Fixtures:
- `phase137_loop_true_break_once_return_add_min.hako`(期待: exit code 3
- `phase137_loop_true_break_once_return_add_const_min.hako`(期待: exit code 8
- `phase137_loop_true_break_once_post_return_add_min.hako`(期待: exit code 13
- Smoke tests:
- VM: 3/3 PASS
- LLVM EXE: 3/3 PASS
- Regression:
- Phase 97: 2/2 PASSnext_non_ws, json_loader_escape
- Phase 131/135/136: 3/3 PASS
- 設計判断Approach A 採用):
- 直接拡張boxification なし)、変更スコープ小
- post_if_post_k.rs は未変更(責任分離)
- 入口: `docs/development/current/main/phases/phase-137/README.md`
---
## 2025-12-18Phase 136 完了 ✅
**Phase 136: loop(true) break-once with return literal**
- 目的: Phase 131-135 を拡張し、return integer literal をサポート
- 仕様:
- `loop(true) { x = 1; break }; return 7` → exit code 7
- `loop(true) { x = 1; break }; x = x + 2; return 7` → exit code 7
- PHI禁止維持、dev-only、既定挙動不変
- 実装:
- `src/mir/control_tree/normalized_shadow/loop_true_break_once.rs``lower_return_value_to_vid()` 行 638-743, Integer literal at 行 661
- Integer literal パターン: Const generationPhase 123 パターン再利用)
- Ok(None) fallback for out-of-scope patterns`return "hello"`, `return 3.14` 等)
- Fixtures:
- `phase136_loop_true_break_once_return_literal_min.hako`(期待: exit code 7
- `phase136_loop_true_break_once_post_return_literal_min.hako`(期待: exit code 7
- Smoke tests:
- VM: 2/2 PASS
- LLVM EXE: 2/2 PASS
- Regression:
- Phase 131: 2/2 PASS
- Phase 135: 2/2 PASS
- 入口: `docs/development/current/main/phases/phase-136/README.md`
---
## 2025-12-18Phase 135 P0 完了 ✅
**Phase 135 P0: Normalization Plan Suffix Detection Generalization**
- 目的: NormalizationPlanBox の suffix 検出を一般化し、post-loop assign が 0 回でも OK に
- 背景:
- Phase 133 までは `loop + assign+ + return`assign 1回以上必須
- Phase 131 は `loop` のみreturn なし)
- ギャップ: `loop + return`0 assignが別経路
- 改善:
- `loop + assign* + return`N >= 0 assignmentsを統一パターンとして検出
- Phase 131 と Phase 132-133 を `LoopWithPost { post_assign_count }` enum で統一
- Phase 131 (loop-only, no return) は `PlanKind::LoopOnly` として独立維持
- 実装:
- `src/mir/builder/control_flow/normalization/plan_box.rs`(検出ロジック修正のみ)
- `post_assign_count >= 1` チェックを削除 → `>= 0` を許容
- `execute_box.rs` は変更なし(既存ロジックが 0 assigns を自然にサポート)
- Fixture: `apps/tests/phase135_loop_true_break_once_post_empty_return_min.hako`(期待: exit code 1
- Smoke tests:
- `phase135_loop_true_break_once_post_empty_return_vm.sh` PASS
- `phase135_loop_true_break_once_post_empty_return_llvm_exe.sh` PASS
- Regression:
- Phase 131: 2/2 PASSVM + LLVM EXE
- Phase 133: 2/2 PASSVM + LLVM EXE
- Unit tests: 9/9 PASSplan_box module
- 設計原則:
- **最小変更**: plan_box.rs の検出条件のみ変更
- **SSOT 維持**: 検出ロジックは plan_box.rs に集約
- **Box-First**: PlanBoxwhatと ExecuteBoxhowの責任分離維持
- 入口: `src/mir/builder/control_flow/normalization/README.md`Phase 135 セクション追加)
## 2025-12-18Phase 133 完了 ✅
**Phase 133: loop(true) break-once + multiple post-loop assignsdev-only**
- 目的: Phase 132 を拡張し、post-loop で複数の assign を受理PHI-free 維持)
- 仕様:
- `loop(true) { x = 1; break }; x = x + 2; x = x + 3; return x` は exit code `6`VM/LLVM EXE parity
- post_nodes 検出を `len() == 2` から `len() >= 2` に拡張
- 複数 assign を iterative に lowerLegacyLowerer::lower_assign_stmt 再利用)
- 実装:
- `src/mir/control_tree/normalized_shadow/loop_true_break_once.rs`3箇所編集、~30行追加
- Pattern detection: all_assigns + ends_with_return
- Post-loop lowering: for loop で複数 assign 処理
- SSOT: env_post_k が最終値を保持ExitMeta に反映)
- Fixture: `apps/tests/phase133_loop_true_break_once_post_multi_add_min.hako`(期待: 6
- Smoke:
- `phase133_loop_true_break_once_post_multi_add_vm.sh` PASS
- `phase133_loop_true_break_once_post_multi_add_llvm_exe.sh` PASS
- Regression: Phase 132/131/97 維持確認(全 PASS
- Unit tests: 1176/1176 PASS
- 入口: `docs/development/current/main/phases/phase-133/README.md`
## 2025-12-18Phase 130 完了 ✅
**Phase 130: if-only Normalized "Small Expr/Assign" Expansiondev-only**
- 目的: post_k 内の最小 post-if 計算(`x = x + 3; return x`)を Normalized で通すPHI禁止
- 実装:
- P1: Assign(Variable) - `x = y` サポートenv map 直接更新)
- P2: Assign(Add) - `x = x + <int literal>` サポートConst + BinOp Add
- P3: Verifier - env map が env layoutwrites + inputs外の変数を導入しないことを検証
- `src/mir/control_tree/normalized_shadow/legacy/mod.rs` (lower_assign_stmt 拡張)
- `src/mir/control_tree/normalized_shadow/normalized_verifier.rs` (verify_env_writes_discipline 追加)
- Fixture: `apps/tests/phase130_if_only_post_if_add_min.hako`(期待出力: 5\n4
- Smoke: `phase130_if_only_post_if_add_vm.sh` PASS
- LLVM EXE smoke: `phase130_if_only_post_if_add_llvm_exe.sh`LLVM 前提が無い環境では SKIP
- Regression: Phase 129/128 維持確認(全 PASS
- Unit tests: 1155/1155 PASS
- 入口: `docs/development/current/main/phases/phase-130/README.md`
## 2025-12-18Phase 129-C 完了 ✅
**Phase 129-C: post-if / post_k continuationdev-only**
- post-if`if { x=2 }; return x`)を post_k continuation で表現
- join_k が env merge → TailCall(post_k, merged_env)
- post_k が post-if statements 実行 → Ret
- PHI禁止: Normalized IR 内に PHI 相当を入れず env 引数で合流
- 実装:
- `src/mir/control_tree/normalized_shadow/post_if_post_k.rs`392行、新規
- `builder.rs` に PostIfPostKBuilderBox 統合
- `normalized_verifier.rs` に post_k 構造検証追加
- `parity_contract.rs` に StructureMismatch 追加
- Fixture: `apps/tests/phase129_if_only_post_if_return_var_min.hako`
- Smoke: `phase129_if_only_post_if_return_var_vm.sh` PASS
- Regression: Phase 129-B, 128 維持確認(全 PASS
- Unit tests: 1155/1155 PASS
- 入口: `docs/development/current/main/phases/phase-129/README.md`
## 2025-12-18Phase 132 完了 ✅
**Phase 132: loop(true) break-once + post-loop minimaldev-only**
- 目的: Phase 131 を拡張し、ループ後の最小 post 計算まで Normalized shadow で固定PHI-free 維持)
- 仕様:
- `loop(true) { x = 1; break }; x = x + 2; return x` は exit code `3`VM/LLVM EXE parity
- post_k continuation で post-loop statements を処理
- 実装:
- **P0**: post_k 生成loop_true_break_once.rs 拡張)
- **P0.5**: StepTree が post-loop statements を保持suffix router box 追加)
- **P1**: k_exit continuation 分類修正(構造ベースの判定)
- **R0**: Continuation SSOT 一本化 + legacy 隔離 + docs 整備
- SSOT:
- `JoinInlineBoundary::default_continuations()` - continuation ID の集約
- `src/mir/builder/control_flow/joinir/merge/README.md` - merge 契約明文化
- `src/mir/builder/control_flow/joinir/legacy/README.md` - legacy 撤去条件
- テスト配置: `src/mir/builder/control_flow/joinir/merge/tests/continuation_contract.rs`
- 検証:
- `bash tools/smokes/v2/profiles/integration/apps/phase132_loop_true_break_once_post_add_vm.sh`
- `bash tools/smokes/v2/profiles/integration/apps/phase132_loop_true_break_once_post_add_llvm_exe.sh`
- 回帰: Phase 131/97 維持確認(全 PASS
- 入口: `docs/development/current/main/phases/phase-132/README.md`
## 2025-12-18Phase 131 P2 完了 ✅
**Phase 131: loop(true) break-once Normalizeddev-only**
- 目的: Normalized shadow の最小ループを VM/LLVM EXE 両方で動かし、更新値が外に見えることまで固定
- 仕様:
- `loop(true) { x = 1; break }; return x` は exit code `1`
- DirectValue modePHI-freeで exit 値を `variable_map` に再接続
- 検証:
- `bash tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_vm.sh`
- `bash tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_llvm_exe.sh`
- 環境: WSL の一時的な EXDEV`Invalid cross-device link`)は `wsl --shutdown` 再起動で解消、上記 + `phase97_next_non_ws_llvm_exe.sh` まで PASS
- 入口: `docs/development/current/main/phases/phase-131/README.md`
## 2025-12-18Phase 127 完了 ✅
**Phase 127: unknown-read strict Fail-Fastdev-only**
- unknown-read = reads - (writes inputs) を検出
- strict: `freeze_with_hint("phase127/unknown_read/<name>", ...)` で即停止hint必須
- dev-only non-strict: 理由ログtag + count + 先頭数件)
- 入口: `docs/development/current/main/phases/phase-127/README.md`
## 2025-12-18Phase 128 完了 ✅
**Phase 128: if-only partial assign keep/merge in Normalized (dev-only)**
- StepStmtKind::Assign に value_ast 追加Phase 128
- Normalized builder に Assign(int literal) 対応env 更新)
- Fixture: phase128_if_only_partial_assign_normalized_min.hako簡易版
- Smoke: phase128_if_only_partial_assign_normalized_vm.shPASS
- Regression: Phase 121-126, 118 維持確認(全 PASS
- Unit tests: 1165/1165 PASS
- 入口: `docs/development/current/main/phases/phase-128/README.md`
- 実装:
- `src/mir/control_tree/step_tree.rs` (value_ast 追加、14行追加)
- `src/mir/control_tree/normalized_shadow/builder.rs` (Assign lowering、87行追加)
- Note: 完全な join_k continuation は future workPhase 128 は基本構造確立)
## 2025-12-18Phase 126 完了 ✅
**Phase 126: available_inputs SSOT wiring (dev-only)**
- AvailableInputsCollectorBox 実装function params + CapturedEnv 収集)
- try_lower_if_only() に available_inputs 配線dev-only
- EnvLayout.inputs が実際に使用されるようになった
- Fixture 強化: reads-only 変数の return 解決を確認
- Regression: Phase 121-125, 118 維持確認(全 PASS
- Unit tests: 28/28 PASS (including 5 new AvailableInputsCollectorBox tests)
- Integration smoke: PASS (phase125_if_only_return_input_vm.sh, exit code 7)
- 入口: `docs/development/current/main/phases/phase-126/README.md`
- 実装:
- `src/mir/control_tree/normalized_shadow/available_inputs_collector.rs` (143行、新規)
- `src/mir/control_tree/normalized_shadow/builder.rs` (available_inputs 配線)
- `src/mir/builder/calls/lowering.rs` (AvailableInputsCollectorBox::collect() 呼び出し)
## 2025-12-18Phase 125 P2-P5 完了 ✅
**Phase 125 P2-P5: Reads-Only Env Inputs (dev-only, structure)**
- EnvLayout 導入writes + inputs の 2 レーン化)
- from_contract: reads ∩ available_inputs で inputs を決定(決定的順序)
- Return(Variable) 解決拡張: writes or inputs から解決
- Fail-Fast with hint: env に無い変数は構造化エラー
- Unit tests: 18/18 PASS (including new test_return_variable_from_inputs_stub)
- Integration smoke: PASS (phase125_if_only_return_input_vm.sh, exit code 7)
- Regression: Phase 121-124, 118 維持確認(全 PASS
- 入口: `docs/development/current/main/phases/phase-125/README.md`
- 実装:
- `src/mir/control_tree/normalized_shadow/builder.rs` (EnvLayout, 186行追加)
- Note: P3 (available_inputs wiring) 未実装、inputs は空structure-only
## 2025-12-18Phase 124 完了 ✅
**Phase 124: Normalized reads facts + Return(Variable from env)dev-only**
- StepTreeFacts に reads 追加Variable 参照を AST から抽出)
- StepTreeContract signature に reads 反映(決定性維持)
- env マッピング(変数名 → ValueIdを writes から生成
- Return(Variable) サポート: env にある変数のみwrites 由来)
- env に無い Variable は Fail-Fast エラーphase124 error → Ok(None) fallback
- Box-first modularization: extract_variables_from_ast() で SSOT 化
- Unit tests: 1159 tests PASS (including test_return_variable_from_env)
- Integration smoke: PASS (`phase124_if_only_return_var_vm.sh`, exit code 7 許容)
- 回帰: Phase 121/123/118 維持確認
- 入口: `docs/development/current/main/phases/phase-124/README.md`
- 実装:
- `src/mir/control_tree/step_tree_facts.rs` (reads 追加、76行)
- `src/mir/control_tree/step_tree_contract_box.rs` (reads 反映、101行)
- `src/mir/control_tree/step_tree.rs` (extract_variables_from_ast 追加、612行)
- `src/mir/control_tree/normalized_shadow/builder.rs` (env マッピング追加、837行)
## 2025-12-18Phase 123 完了 ✅
**Phase 123: if-only Normalized semanticsdev-only**
- Return(Integer literal) → `Const + Ret(Some(vid))` 生成
- Return(Variable) → `Ok(None)` (graceful degradation, Phase 124 で対応)
- If(minimal compare) → Variable vs Integer literal のみ対応
- Graceful degradation: Phase 123 制限は `Ok(None)` で legacy に fallback
- Structured error codes: `[phase123/...]` prefix で明示的エラー
- Box-first modularization: parse/verify/lower 責務分離
- Unit tests: 8 tests PASS (including graceful degradation test)
- Integration smoke: PASS (`phase123_if_only_normalized_semantics_vm.sh`)
- 入口: `docs/development/current/main/phases/phase-123/README.md`
## 2025-12-18Phase 121 完了 ✅
**Phase 121: StepTree→Normalized Shadow Lowering (if-only, dev-only)**
- 箱化モジュール化: normalized_shadow/{contracts,builder,parity}.rs (508行、新規)
- Shadow lowering: StepTree → JoinModule (Normalized方言、if-only限定)
- Capability guard: Loop/Break/Continue を明示的拒否SSOT
- Parity 検証: exit contracts + writes 比較dev ログ / strict fail-fast
- Dev-only wiring: `joinir_dev_enabled()` のときのみ shadow 生成
- Strict fail-fast: `freeze_with_hint` で mismatch を即座に検出hint必須
- Smoke tests: VM 3/3 PASS、LLVM スタブ(ハーネス設定必要)
- 回帰: Phase 120 維持確認、全テスト PASS
- 入口: `docs/development/current/main/phases/phase-121/README.md`
- 設計: `docs/development/current/main/design/control-tree.md` (Phase 121章)
## 2025-12-18Phase 120 完了 ✅
**Phase 120: StepTree "Facts→Decision→Emit" 箱化モジュール化**
- 箱化モジュール化: StepTreeFacts / StepTreeContractBox の責務分離
- StepTreeBuilderBox: 構造 + facts 抽出まで(意思決定・整形・署名生成はしない)
- StepTreeContractBox: facts → contract の整形のみidempotent, deterministic
- BTreeSet で順序決定性保証facts は順序に依存しない)
- signature_basis_string() の決定性維持(既定挙動不変)
- 回帰: Phase 103/118 維持確認、全 1142 テスト PASS
- 入口: `docs/development/current/main/design/control-tree.md`
- 実装:
- `src/mir/control_tree/step_tree_facts.rs` (63行、新規)
- `src/mir/control_tree/step_tree_contract_box.rs` (168行、新規)
- `src/mir/control_tree/step_tree.rs` (262→411行、リファクタリング)
## 2025-12-18Phase 119 完了 ✅
**Phase 119: StepTree cond SSOTAST handle**
- StepNode::If / StepNode::Loop に cond_ast (AstNodeHandle) を追加
- SSOT: cond は AST 参照を保持、cond_sig は派生(署名/ログ/差分検知)
- 不変条件: cond_ast は signature_basis_string() に混ぜない(決定性維持)
- 実装: Box<ASTNode> clonedev-only なので許容)
- 回帰: Phase 103/104/118 維持確認
- 入口: `docs/development/current/main/design/control-tree.md`
## 2025-12-18Phase 118 完了 ✅
**Phase 118: loop + if-only merge parity**
- loop + if-only で条件付き変数更新 merge を VM/LLVM で固定
- Fixture: phase118_loop_nested_if_merge_min.hako (expected: 2)
- Pattern3 (if-sum) 活用
- Smoke: VM + LLVM EXE parity 検証済み
- Follow-up: Pattern3 carrier PHI contractexpected: 12
- Fixture: phase118_pattern3_if_sum_min.hako
- Smoke: phase118_pattern3_if_sum_{vm,llvm_exe}.sh
- 回帰: Phase 117 維持確認
- 入口: `docs/development/current/main/phases/phase-118/README.md`
## 2025-12-18Phase 117 完了 ✅
**Phase 117: if-only nested-if + call merge parity**
- ネストしたif-only内側if + 外側elseで call 結果 merge を VM/LLVM で固定
- Fixture: phase117_if_only_nested_if_call_merge_min.hako (expected: 2, 3, 4)
- Smoke: VM + LLVM EXE parity 検証済み
- 回帰: Phase 116 維持確認
- 入口: `docs/development/current/main/phases/phase-117/README.md`
## 2025-12-18Phase 116 完了 ✅
**Phase 116: if-only keep+call merge parity**
- if-only で片側が元値保持、片側が call 結果のパターンを VM/LLVM で固定
- Fixture: phase116_if_only_keep_plus_call_min.hako (expected: 10, 2)
- Smoke: VM + LLVM EXE parity 検証済み
- 回帰: Phase 115 維持確認
- 入口: `docs/development/current/main/phases/phase-116/README.md`
## 2025-12-18Phase 115 完了 ✅
**Phase 115: if-only call result merge parity**
- if-only で関数呼び出し結果を merge するパターンを VM/LLVM で固定
- Fixture: phase115_if_only_call_merge_min.hako (expected: 2, 3)
- Smoke: VM + LLVM EXE parity 検証済み
- 回帰: Phase 103/113/114 維持確認
- 入口: `docs/development/current/main/phases/phase-115/README.md`
## 2025-12-18Phase 114 完了 ✅
**Phase 114: if-only return+post parity**
- if-only で early return + post-if statements パターンを VM/LLVM で固定
- Fixture: phase114_if_only_return_then_post_min.hako (expected: 7, 2)
- Smoke: VM + LLVM EXE parity 検証済み
- 回帰: Phase 103/113 維持確認
- 入口: `docs/development/current/main/phases/phase-114/README.md`
## 2025-12-18Phase 113 完了 ✅
**Phase 113: if-only partial assign parity**
- if-onlyelse なし)の片側代入で「保持 merge」パターンを VM/LLVM で固定
- Fixture: phase113_if_only_partial_assign_min.hako
- Smoke: VM + LLVM EXE parity 検証済み
## 2025-12-18Phase 112 完了 ✅
**Phase 112: StepTree Capability Guard (strict-only)**
- StepTree の required_caps を strict mode でチェック
- Allowlist: If, NestedIf, Loop, Return, Break, Continue
- Deny (strict): NestedLoop, TryCatch, Throw, Lambda, While, ForRange, Match, Arrow
- Error format: `[joinir/control_tree/cap_missing/<Cap>] <msg> Hint: <hint>`
- Default behavior unchanged (strict=false always Ok)
- 入口: `docs/development/current/main/design/control-tree.md`
- 実装:
- `src/mir/builder/control_flow/joinir/control_tree_capability_guard.rs`
- `src/mir/builder/calls/lowering.rs` (wired into lower_function_body)
## 2025-12-18Phase 111 完了 ✅
**Phase 111: StepTreeContract + StepTreeSignaturedev-only**
- StepTreeContract を追加(`exits` / `writes` / `required_caps` / `cond_sig`
- StepTreeSignature を追加(`signature_basis_string()` を安定 hash、Span は含めない)
- dev-only parity を break/continue に加えて return まで拡張
- 入口: `docs/development/current/main/design/control-tree.md`
- 実装: `src/mir/control_tree/step_tree.rs`
## 2025-12-18Phase 110 完了 ✅
**Phase 110: ControlTree / StepTree構造SSOT・dev-only観測**
- StepTree の語彙Block/If/Loop/Stmtと Feature を pure AST で実装ValueId/PHI/CFG を混ぜない)
- joinir routing 側で extractor との “分類矛盾” を dev-only で検出strict のみ Fail-Fast
- 関数本体の StepTree を dev-only でダンプ(既定挙動不変)
- 入口: `docs/development/current/main/design/control-tree.md`
- 実装:
- `src/mir/control_tree/step_tree.rs`
- `src/mir/builder/calls/lowering.rs`
- `src/mir/builder/control_flow/joinir/routing.rs`
## 2025-12-17Phase 109 完了 ✅
**Phase 109: error_tags hints SSOT**
- policy/validator エラーを "tag + message + hint" 形式に統一
- freeze_with_hint() API 追加hint 必須、空なら panic
- Phase 107/104/100 の代表3箱を hint 対応に移行
- 入口: `docs/development/current/main/phases/phase-109/README.md`
## 2025-12-17Phase 104 完了 ✅
**Phase 104: loop(true) + break-only digitsread_digits 系)**
- read_digits_from 形の `loop(true)` を Pattern2 で受理loop var 抽出 + break cond 正規化)
- fixture: `apps/tests/phase104_read_digits_loop_true_min.hako`expected: `2`, `1`
- smoke: `tools/smokes/v2/profiles/integration/apps/phase104_read_digits_vm.sh` / `tools/smokes/v2/profiles/integration/apps/phase104_read_digits_llvm_exe.sh`
- P2: json_cur 由来の回帰面を追加fixture+VM/LLVM EXE smoke
## 2025-12-17Phase 107 完了 ✅
**Phase 107: json_cur find_balanced_* depth scanVM + LLVM EXE parity**
- depth scan + nested if + return-in-loop を Pattern2 policy で受理hardcode なし)
- fixture:
- `apps/tests/phase107_find_balanced_array_end_min.hako`expected: `1`, `3`
- `apps/tests/phase107_find_balanced_object_end_min.hako`expected: `1`, `3`
- smokeintegration:
- VM: `tools/smokes/v2/profiles/integration/apps/phase107_find_balanced_array_end_vm.sh` / `tools/smokes/v2/profiles/integration/apps/phase107_find_balanced_object_end_vm.sh`
- LLVM EXE: `tools/smokes/v2/profiles/integration/apps/phase107_find_balanced_array_end_llvm_exe.sh` / `tools/smokes/v2/profiles/integration/apps/phase107_find_balanced_object_end_llvm_exe.sh`
- 入口: `docs/development/current/main/phases/phase-107/README.md`
## 2025-12-17Phase 108 完了 ✅
**Phase 108: Pattern2 policy router SSOT薄い入口の固定**
- post-loop early return を一般 plan`cond`/`ret_expr`として独立し、Pattern2Inputs の依存を解消
- ApplyPolicyStepBox から “直叩き” を撤去し、policy router 1本に集約入口SSOT
- 入口: `docs/development/current/main/phases/phase-108/README.md`
## 2025-12-17Phase 103 P0 完了 ✅
**Phase 103: if-only regression baseline**
- if-onlyloop無しの nested if + merge を fixture 化し、VM/LLVM EXE parity を integration smoke で固定
## 2025-12-17Phase 100 P3 完了 ✅
**Phase 100 P3: String Accumulator Captures**
- String accumulator`out = out + ch`を最小形で固定し、VM/LLVM EXE parity を smoke で検証
- LLVM EXE 側の stringish 伝播PHI/copy/binopを修正し、concat の意味論を安定化
## 2025-12-17Phase 100 P2 完了 ✅
**Phase 100 P2: Mutable Accumulator Captures**
- Mutable accumulator pattern (`out = out + ch`) を Pattern2 carrier で対応
- ScopeManager 委譲により read-only check を回避
- Numeric output validation (count=3) で fixture 固定
- VM/LLVM EXE parity 完了smoke 追加)
## 2025-12-17Phase 100 P1 完了 ✅
**Phase 100 P1: Pinned Local Captures**
- CapturedEnv に CapturedKind (Explicit/Pinned) 拡張
- PinnedLocalAnalyzer で loop-outer read-only locals を識別
- Pinned receiver (例: s.substring()) が loop 内で使用可能に
- Fixture/smoke で動作確認済み
## 20251217Phase 99 完了 ✅
**Phase 99: Trim/escape 実コード寄り強化VM+LLVM EXE**
- next_non_ws を3ケース固定`2`, `-1`, `3`)— 改行/CR/Tab混在パターン追加
- escape 末尾バックスラッシュを best-effort として固定(`hello\` そのまま出力)
- VM+LLVM EXE parity 完全対応、integration smoke で検証済み
関連(設計/実装の入口):
- Phase 100: `docs/development/current/main/phases/phase-100/README.md`
## 20251215Phase 132 完了 ✅
**Phase 132: LLVM Exit PHI=0 根治修正 完了!**
- ループ exit PHI が 0 を返す問題を根治解決
- 原因2層: (1) JoinIR/Boundary が exit 値を境界に渡していない、(2) LLVM Python が PHI を落とす/上書きする
- 修正: Pattern 1 で exit 値を明示的に渡す + `predeclared_ret_phis` 使用 + `builder.vmap` の PHI 保護
- 結果: `/tmp/p1_return_i.hako` が 3 を返すVM 一致)
- 詳細: `investigations/phase132-llvm-exit-phi-wrong-result.md`
**追加Phase 132-P2: Case C の Exit PHI ValueId 衝突を修正**
- 原因: `exit_phi_builder.rs` が module-level allocator を使い、同一関数内で ValueId が衝突し得た
- 修正: `func.next_value_id()`function-levelへ統一`bd07b7f4`
- 結果: `apps/tests/llvm_stage3_loop_only.hako` が LLVM EXE でも `Result: 3`VM 一致)
- 詳細: `investigations/phase132-case-c-llvm-exe.md`
**追加Phase 132-P3: Exit PHI collision の早期検出debug-only**
- `verify_exit_phi_no_collision()``contract_checks.rs` に追加し、ValueId 衝突を JoinIR merge の段階で Fail-Fast する
## 20251215Phase 133136短報
- Phase 133: promoted carrierTrim`join_id` 解決を SSOT に寄せて修正smoke は compile-only
- Phase 134: plugin loader best-effort loading を導入(決定的順序 + failure 集約 + 継続)。
- Phase 135: ConditionLoweringBox が allocator SSOT を無視して ValueId 衝突を起こす問題を根治。
- 詳細: `docs/development/current/main/phases/phase-135/README.md`
- Phase 136: MirBuilder の Context 分割を完了し、状態の SSOT を Context に一本化。
- 詳細: `docs/development/current/main/phases/phase-136/README.md`
## 20251216Phase 137141短報
- Loop Canonicalizer前処理 SSOTは Phase 141 まで完了既定挙動は不変、dev-only 観測/strict parity あり)。
- 設計 SSOT: `docs/development/current/main/design/loop-canonicalizer.md`
- 実装: `src/mir/loop_canonicalizer/mod.rs`+ 観測: `src/mir/builder/control_flow/joinir/routing.rs`
- Phase 記録: `docs/development/current/main/phases/phase-137/README.md`
## 20251216Phase 92短報
- Phase 92ConditionalStep / P5b escape の lowering 基盤)は完了。
- 条件付き更新(`ConditionalStep`のJoinIR表現 + Pattern2 側の委譲emitter 箱化)
- 条件式での body-local 参照(`ConditionEnv → LoopBodyLocalEnv`+ 最小E2E smoke 固定
- Phase 記録SSOT入口: `docs/development/current/main/phases/phase-92/README.md`
- 残: P5b の “完全E2E” は body-local promotion 拡張後(スコープ外で保留)
## 20251216Phase 93短報
- Trim の `is_ch_match` など「ConditionOnlyPHIで運ばない派生値」を Derived Slot として毎イテレーション再計算できるようにした。
- SSOT: `ConditionOnlyRecipe`(運搬禁止)+ `ConditionOnlyEmitter`
- schedule: `body-init → derived → break` を評価順SSOTとして強制
- Phase 記録(入口): `docs/development/current/main/phases/phase-93/README.md`
## 20251216Phase 94短報
- P5b escape`ch` 再代入 + `i` の +1/+2を “derivedSelect” として扱い、VM E2E を固定。
- 新箱: `BodyLocalDerivedEmitter` + 明示ポリシーstrict で理由付き Fail-Fast
- integration smoke: `tools/smokes/v2/profiles/integration/apps/phase94_p5b_escape_e2e.sh`
- Phase 記録(入口): `docs/development/current/main/phases/phase-94/README.md`
## 20251216Phase 95短報
- MiniJsonLoader の escape ループを Phase 94 基盤で固定(派生 body-local + 条件付き skip
- フィクスチャ: `apps/tests/phase95_json_loader_escape_min.hako`
- smoke: `tools/smokes/v2/profiles/integration/apps/phase95_json_loader_escape_vm.sh`
- Phase 記録(入口): `docs/development/current/main/phases/phase-95/README.md`
## 20251216Phase 96短報
- Trim系 policy 化を開始し、MiniJsonLoader の next_non_ws ループを fixtures/smoke に追加。
- フィクスチャ: `apps/tests/phase96_json_loader_next_non_ws_min.hako`
- smoke: `tools/smokes/v2/profiles/integration/apps/phase96_json_loader_next_non_ws_vm.sh`
- Phase 記録(入口): `docs/development/current/main/phases/phase-96/README.md`
## 20251216Phase 97短報
- Phase 95/96 の MiniJsonLoader fixture を LLVM EXE ラインでも固定し、JoinIR/Trim の退行検出を強化。
- smoke: `tools/smokes/v2/profiles/integration/apps/phase97_next_non_ws_llvm_exe.sh`next_non_ws
- smoke: `tools/smokes/v2/profiles/integration/apps/phase97_json_loader_escape_llvm_exe.sh`escape
- Phase 記録(入口): `docs/development/current/main/phases/phase-97/README.md`
## 20251217Phase 98短報
- plugin loader に strict fail-fast を導入しHAKO_JOINIR_STRICT=1、FileBox/MapBox の LLVM EXE parity を持続可能に。
- smoke: `tools/smokes/v2/profiles/integration/apps/phase97_next_non_ws_llvm_exe.sh`
- smoke: `tools/smokes/v2/profiles/integration/apps/phase97_json_loader_escape_llvm_exe.sh`
- Phase 記録(入口): `docs/development/current/main/phases/phase-98/README.md`
## 20251217Phase 102短報
- real-appMiniJsonLoader.read_quoted_fromの loop を最小抽出し、VM + LLVM EXE で regression を固定(期待: length=4
- フィクスチャ: `apps/tests/phase102_realapp_read_quoted_min.hako`
- smoke: `tools/smokes/v2/profiles/integration/apps/phase102_realapp_read_quoted_vm.sh`
- smoke: `tools/smokes/v2/profiles/integration/apps/phase102_realapp_read_quoted_llvm_exe.sh`
- Phase 記録(入口): `docs/development/current/main/phases/phase-102/README.md`
## 20251214現状サマリ
補足docs が増えて迷子になったときの「置き場所ルールSSOT」:
- `docs/development/current/main/DOCS_LAYOUT.md`
### JoinIR / Loop / If ライン
- LoopBuilder は Phase 186187 で完全削除済み。**JoinIR が唯一の loop lowering 経路**。
- LoopPattern 系は Pattern14 まで実装・本線化済み:
- Pattern1: Simple While
- Pattern2: Loop with Break
- Pattern3: Loop with IfElse PHIbreak/continue なし)
- Pattern4: Loop with Continuemulticarrier 対応)
- Exit/Carrier/Boundary ラインは次の箱で SSOT 化:
- `CarrierInfo` / `ExitMeta` / `ExitBindingBuilder`
- `JoinInlineBoundary` + `LoopExitBinding`
- If lowering は IfSelectLowerer/IfMergeLowerer を中心に整理済み。Select/PHI の扱いも Phase 189 系で橋渡し済み。
- 残課題JoinIR ライン):
- JoinIR→MIR merge の一般化(複雑な Select/PHI パターンの統合)
- JsonParserBox など実アプリ側での長期運用テスト
- Phase 8690Loop frontendsまとめ1枚:
- `docs/development/current/main/phase86-90-loop-frontends-summary.md`
### Phase 8690: Loop frontends要約
- Phase 8690 は “dev-only fixtures + shape guard + fail-fast” で段階的に固定済み。
- 具体の fixture / shape / 未検証は `docs/development/current/main/phase86-90-loop-frontends-summary.md` を SSOT とする。
### Scope / BindingIddev-only の段階移行ライン)
- MIR builder 側で lexical scope / shadowing を実在化し、言語仕様の “local はブロック境界で分離” を SSOT に揃えた。
- JoinIR lowering 側は name-based から BindingId-based へ段階移行中:
- `ScopeManager.lookup_with_binding()` / `ConditionEnv.binding_id_map` を導入し、shadowing を壊さずに解決できる足場を作った。
- promoted carriersDigitPos/Trimについては `BindingId(original) → BindingId(promoted) → ValueId(join)` の鎖を dev-only で整備中。
- Phase 86 で `carrier_init_builder` / `error_tags` を SSOT 化し、段階移行ラインの基盤ValueId 生成とエラー語彙)が確立した。
- これにより、BindingId dual-path の拡張・統合時に「生成」と「表示」の責務が混ざらない構造が固定された。
- Phase 81 で Pattern2DigitPos/Trimの ExitLine 契約ConditionOnly を exit PHI から除外、LoopState のみを reconnectを E2E で固定した。
- 参照:
- `docs/development/current/main/phase73-scope-manager-design.md`
- `docs/development/current/main/phase78-bindingid-promoted-carriers.md`
- `docs/development/current/main/phase80-bindingid-p3p4-plan.md`
- `docs/development/current/main/phase81-pattern2-exitline-contract.md`
- `docs/development/current/main/phase78-85-boxification-feedback.md`
### JsonParser / Selfhost depth2 ライン
- `selfhost_build.sh --json` で Program JSON v0 emit は安定。
`.hako` 側から env 経由で JSON を読む最小ループ(`program_read_min.hako`)は動作確認済み。
- JsonParserBox / BundleResolver のループ 21 本のうち:
- 18 本は Pattern14 で JoinIR 対応済みPhase 162165
- `_trim` を含む一部の複合ループは、ValueId 境界や Box 登録など残課題あり。
- BoolExprLowerer / condition_to_joinir で OR/AND/NOT 付き条件式の lowering は実装完了Phase 168169
- 残課題JsonParser/selfhost depth2
- JoinIR→MIR ValueId boundary の完全一般化(条件用 ValueId を含める)
- JsonParserBox の using / Box 登録Rust VM 側での認識)
- Program JSON v0 を JsonParserBox 経由でフル解析する line の仕上げ
### Ring0 / Runtime / CoreServices ライン
- Ring0Context + Ring0Registry で OS API 抽象化レイヤ完成:
- MemApi / IoApi / TimeApi / LogApi / FsApi / ThreadApi
- RuntimeProfile(Default / NoFs) で条件付き必須を制御。
- CoreServicesring1coreとして次を実装済み
- StringService / IntegerService / BoolService
- ArrayService / MapService / ConsoleService
- PluginHost 統合 + UnifiedBoxRegistry からの自動初期化
- FileBox / FileHandleBox ライン:
- Ring0FsFileIo 経由で read / write / append / metadata 完全対応
- Default プロファイルでは必須、NoFs プロファイルでは disabled。
- Logging ライン:
- ConsoleServiceuserfacing
- Ring0.loginternal/dev
- println!test 専用)
の 3 層が `logging_policy.md` で整理済み。JoinIR/Loop trace も同ドキュメントに集約。
- VM backend の Box 解決UnifiedBoxRegistry / BoxFactoryRegistryの経路図:
- `docs/development/current/main/phase131-2-box-resolution-map.md`
- LLVMPython llvmlitelowering の棚卸しPhase 131-3..10:
- `docs/development/current/main/phase131-3-llvm-lowering-inventory.md`
- 状態: Case BPattern1/loop_min_whileは EMIT/LINK/RUN まで復旧済み。Phase 132 で `return i` の VM/LLVM parity を固定。
- Case C は別途 “Case C docs” を SSOT にして追跡する(状況は更新されるので、この箇所では断定しない)
- Case C の調査と実装計画:
- `docs/development/current/main/phase131-11-case-c-summary.md`
- `docs/development/current/main/case-c-infinite-loop-analysis.md`
---
## 20250908旧スナップショット参考
- LLVM 側 P0 完了BitOps/Array/Echo/Map 緑。VInvoke(byname/byid vector) は戻り値マッピングの暫定課題を確認中Decisions 参照)。
- selfhosting-dev の作業を main に順次取り込み。VM/MIR 基盤は main で先に整える方針。
直近タスク(当時)
1) continue/break の loweringBuilder 修正のみで表現)
- ループ文脈スタック {head, exit} を導入。
- continue に遭遇 → headまたは latchへ br を emit し終端。
- break に遭遇 → exit へ br を emit し終端。
- postterminated 後に emit しない制御を徹底。
2) ループ CFG の厳密化
- 単一 exit ブロックの徹底。
- Phi はヘッダでキャリー変数を合流SSA/支配関係が崩れない形)。
3) 検証とスモーク
- Verifier 緑dominance/SSA
- VM のループ代表(単純/ネスト/早期継続・脱出)。
- LLVM/Cranelift EXE に綺麗に降りるbr/phi ベースで問題なし)。
代表コマンド(例)
- ビルド: `cargo build --release`
- LLVM smoke: `LLVM_SYS_180_PREFIX=$(llvm-config-18 --prefix) NYASH_LLVM_BITOPS_SMOKE=1 ./tools/llvm_smoke.sh release`
- VInvoke 調査: `NYASH_LLVM_VINVOKE_TRACE=1 NYASH_LLVM_VINVOKE_SMOKE=1 ./tools/llvm_smoke.sh release`