Commit Graph

408 Commits

Author SHA1 Message Date
daf1827c03 test(joinir): Phase 128 - add fixture + smoke test (VM)
- Fixture: phase128_if_only_partial_assign_normalized_min.hako
  - Tests basic assign lowering with if/return pattern
  - Expected output: 2 (from then branch with print)
- Smoke: phase128_if_only_partial_assign_normalized_vm.sh
  - Validates output: 2 with exit code 0
  - Dev-only: NYASH_JOINIR_DEV=1 HAKO_JOINIR_STRICT=1
- Result: PASS
2025-12-18 07:07:04 +09:00
92b3c2afb5 test(joinir): Phase 125 P5 fixture + smoke (VM, structure-only)
Phase 125 P5: Integration smoke test
- fixture: apps/tests/phase125_if_only_return_readonly_input_min.hako
  - Expected: 7 (return x from reads-only input)
  - Note: Demonstrates structure, full functionality needs P3 wiring
- smoke: tools/smokes/v2/profiles/integration/apps/phase125_if_only_return_input_vm.sh
  - NYASH_JOINIR_DEV=1 HAKO_JOINIR_STRICT=1
  - VM backend only

Test results:
- Phase 125 smoke: PASS (exit code 7)
- Regression (Phase 121-124, 118): PASS
  - phase124_if_only_return_var_vm: PASS
  - phase123_if_only_normalized_semantics_vm: PASS
  - phase121_shadow_if_only_vm: PASS (3/3 tests)
  - phase118_loop_nested_if_merge_vm: PASS

Note:
- P3 (available_inputs wiring) not implemented yet
- Fixture uses simple return (no if-only pattern yet)
- Serves as design document for future P3 implementation
- EnvLayout.inputs will be populated when P3 is complete

Ref: docs/development/current/main/phases/phase-125/README.md
2025-12-18 06:32:10 +09:00
8e6791a623 test(joinir): Phase 124 return-var normalized smoke (VM)
Phase 124-P4:
- Add fixture: apps/tests/phase124_if_only_return_var_min.hako
  - local x; x = 7; print(x); return x
  - Expected output: 7 (print), RC: 7 (return x)
- Add smoke: tools/smokes/v2/profiles/integration/apps/phase124_if_only_return_var_vm.sh
  - NYASH_JOINIR_DEV=1 HAKO_JOINIR_STRICT=1 for dev-only features
  - Accept exit code 7 (return x where x=7) as valid
- Verify all Phase 121/123/118 smokes still PASS
2025-12-18 06:09:36 +09:00
b3cd7c0884 test(joinir): Phase 123 normalized semantics smoke (VM)
Adds integration smoke test for Phase 123 normalized semantics lowering.

**New Files**:
- `apps/tests/phase123_if_only_return_literal_min.hako`: Minimal test fixture (output: 7)
- `tools/smokes/v2/profiles/integration/apps/phase123_if_only_normalized_semantics_vm.sh`: Smoke test script

**What's Tested**:
- Return(Integer literal) generates correct output
- Dev+strict mode does not fail (graceful degradation works)

**Test Status**: PASS

**Verification**:
```bash
bash tools/smokes/v2/profiles/integration/apps/phase123_if_only_normalized_semantics_vm.sh
# Result: PASS (output: 7)
```

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 05:50:16 +09:00
4abd434366 test: Phase 122 if-only Normalized emit smoke
Phase 122 P4: Fixtures and smoke tests
- New fixture: phase122_if_only_normalized_emit_min.hako
- Smoke test: phase122_if_only_normalized_emit_vm.sh
- Verifies: module emission + structure verification in dev+strict mode
- Regression check: phase103 fixture still passes
- All tests PASS
2025-12-18 04:53:04 +09:00
0892df6dff test(joinir): Phase 121 shadow parity smokes (VM + LLVM EXE) 2025-12-18 04:39:23 +09:00
8fb393b5e8 test(joinir): Phase 118 loop+if merge parity smokes 2025-12-18 03:43:10 +09:00
bc561682f6 test: Phase 117 if-only nested-if call merge parity (VM + LLVM EXE)
Fixture & Smoke tests for nested if-only with call merge verification.

**Fixture**:
- apps/tests/phase117_if_only_nested_if_call_merge_min.hako
- Pattern: nested if (inner: b == 1) inside outer if (a == 1), outer else
- Call merge: f(1), f(2), f(3) results merged to single variable v
- Expected output: 2, 3, 4 (f(x) = x + 1)

**VM Smoke**:
- tools/smokes/v2/profiles/integration/apps/phase117_if_only_nested_if_call_merge_vm.sh
- Execution: NYASH_DISABLE_PLUGINS=1 HAKO_JOINIR_STRICT=1
- Validation: numeric output 3 lines "2\n3\n4"

**LLVM EXE Smoke**:
- tools/smokes/v2/profiles/integration/apps/phase117_if_only_nested_if_call_merge_llvm_exe.sh
- Required plugins: FileBox, MapBox, StringBox, ConsoleBox, IntegerBox
- Validation: numeric output "2\n3\n4" (3 lines)

**Verification**:
 VM smoke: PASS
 LLVM EXE smoke: PASS
 Regression (Phase 116): PASS

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 02:55:02 +09:00
ed38aa820a test: Phase 116 if-only keep+call merge parity (VM + LLVM EXE)
Phase 116 固定: if-only で片側が元値保持、片側が call 結果の merge パターン

## 実装内容

### Fixture
- `apps/tests/phase116_if_only_keep_plus_call_min.hako`
- Expected output: `10\n2`
- Pattern:
  - then側: call結果でvを更新 (`v = f(1)`)
  - else側: 元の値を保持 (`v = 10`)
  - merge地点: 異なるソース(元値 vs call結果)からのPHI

### Smoke Tests
- `phase116_if_only_keep_plus_call_vm.sh` - VM parity
  - output_validator.sh で数値2行 `10\n2` を検証
  - `NYASH_DISABLE_PLUGINS=1 HAKO_JOINIR_STRICT=1`
- `phase116_if_only_keep_plus_call_llvm_exe.sh` - LLVM EXE parity
  - llvm_exe_runner.sh を利用(plugin dlopen/cache/build-all SSOT)
  - llvm_exe_build_and_run_numeric_smoke で検証

## 検証結果

 VM smoke: PASS (10\n2)
 LLVM EXE smoke: PASS (10\n2)
 回帰 (Phase 115): PASS (2\n3)

## 技術的詳細

### JoinIR Pattern 1 (Simple If)

```
entry_block:
  v = 10
  if flag == 1 goto then_block else exit_block

then_block:
  v = f(1)
  goto exit_block

exit_block:
  v_merged = PHI [v=10 from entry, v=f(1) from then]
  print(v_merged)
```

### PHI接続の重要性
- entry → exit: 元値 (`10`) を直接伝播
- then → exit: call結果 (`f(1)`) を伝播
- PHI: 異なる型のソース(変数 vs call結果)を正しくmerge

LLVM IRでは、これらが適切な型で統一される必要がある。

## Box-First原則の適用

 既存の箱化されたコンポーネントを活用
  - output_validator.sh による出力検証の統一
  - llvm_exe_runner.sh によるLLVM実行の標準化
  - テストインフラの再利用(no reinvention)

## Fail-Fast原則

 VM/LLVM両方でエラーを即座に検出
  - `HAKO_JOINIR_STRICT=1` で厳密な検証
  - フォールバック処理なし(エラーは明示的に失敗)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 02:39:33 +09:00
5602aff8a9 refactor(smokes): add output_validator.sh for SSOT numeric assertion
Output検証をSSOT化して保守性を向上

**新規追加**:
- tools/smokes/v2/lib/output_validator.sh
  - extract_numeric_lines N: 数値行をN行抽出(パターンマッチング)
  - assert_equals_multiline EXPECTED ACTUAL: 複数行期待値と比較
  - validate_numeric_output N EXPECTED OUTPUT: extract + assert の合成Box

**リファクタリング対象** (5ファイル):
- phase103_if_only_vm.sh
- phase103_if_only_early_return_vm.sh
- phase113_if_only_partial_assign_vm.sh
- phase114_if_only_return_then_post_vm.sh
- phase115_if_only_call_merge_vm.sh

**変更内容**:
- 重複パターン `grep -E '^-?[0-9]+$' | head -n N` → `extract_numeric_lines N`
- 比較ロジック → `validate_numeric_output` に統一
- 各smokeは `source output_validator.sh` で共通機能を利用

**検証結果**:
- phase103_if_only_vm: PASS 
- phase103_if_only_early_return_vm: PASS 
- phase113_if_only_partial_assign_vm: PASS 
- phase114_if_only_return_then_post_vm: PASS 
- phase115_if_only_call_merge_vm: PASS 

**箱化モジュール化の成果**:
- 単一責任: extract_numeric_lines(抽出のみ)、assert_equals_multiline(比較のみ)
- 分離: 各機能が独立したBox(テスト容易性向上)
- 合成: validate_numeric_output が extract + assert を組み合わせ
- Fail-Fast: 全関数でパラメータチェック(明示的エラー)
- 保守性: 検証パターン変更時は output_validator.sh の1箇所のみ修正

**設計原則**:
- Box-First: 機能を箱に切り出して境界を明確化
- SSOT: 数値行抽出と検証ロジックを1箇所に集約
- Fail-Fast: パラメータ不正時は即座にエラー(フォールバックなし)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 02:32:32 +09:00
0a29f1443e test: Phase 115 if-only call result merge parity (VM + LLVM EXE)
Phase 115実装 - if分岐内での関数呼び出し結果をマージするパターンを固定

**実装内容**:
- Fixture: phase115_if_only_call_merge_min.hako (expected: 2, 3)
  - if/else両分岐で関数呼び出し f() の結果を変数 v に代入
  - if後にマージされた v を使用(LLVM EXE でのPHI node生成を検証)
- VM smoke: phase115_if_only_call_merge_vm.sh
  - NYASH_DISABLE_PLUGINS=1 HAKO_JOINIR_STRICT=1 で実行
- LLVM EXE smoke: phase115_if_only_call_merge_llvm_exe.sh
  - llvm_exe_runner.sh を利用した標準パリティ検証

**検証結果**:
- VM test: PASS 
- LLVM EXE test: PASS 
- Phase 114 regression: PASS 

**箱化モジュール化の観点**:
- 単一責任: 各smokeは1パターンのみ検証(call result merge)
- 分離: VM/LLVM EXEで独立したテスト(llvm_exe_runner.sh経由)
- Fail-Fast: HAKO_JOINIR_STRICT=1 で不正な制御フローを即座に検出

**関連**:
- Phase 103: If-Only基本パリティ(制御フロー基礎)
- Phase 113: If-Only部分代入パリティ(変数マージ)
- Phase 114: If-Only return+post パリティ(early returnとpost-if文)
- Phase 115: If-Only call result merge パリティ(関数呼び出し結果マージ) ← 今回

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 02:32:08 +09:00
80be814fa4 test: Phase 114 if-only return+post parity (VM + LLVM EXE)
Phase 114 validates that if-only lowering correctly handles cases with:
- Early return in the if-only branch
- Post-if statements that execute on the else path
- Different return values from each path

Fixture: apps/tests/phase114_if_only_return_then_post_min.hako
- Expected output: 7\n2
- f(1): condition true → early return 7
- f(0): condition false → x=1+1=2, return 2

Testing:
- VM backend: phase114_if_only_return_then_post_vm.sh 
- LLVM EXE backend: phase114_if_only_return_then_post_llvm_exe.sh 
- Regression: Phase 103/113 maintained 

Implementation: No new code required - validates existing if-only
exit line routing and post-if statement processing.

Documentation:
- docs/development/current/main/phases/phase-114/README.md
- Updated: 10-Now.md, 01-JoinIR-Selfhost-INDEX.md

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 02:18:57 +09:00
ba25fe6d01 test: Phase 113 if-only partial assign fixture + smokes (VM + LLVM)
- Add apps/tests/phase113_if_only_partial_assign_min.hako
  * Pattern: x=1; if flag==1 { x=2 } print(x)
  * Tests "preserve merge" on else side
- Add VM smoke: phase113_if_only_partial_assign_vm.sh
- Add LLVM EXE smoke: phase113_if_only_partial_assign_llvm_exe.sh
- Expected output: 1\n2 (flag=0 preserves, flag=1 updates)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 01:58:38 +09:00
9fa2f5a8ad test: align Phase 107 object fixture expected output 2025-12-17 23:16:53 +09:00
3c934dc69d test: Phase 107 add find_balanced_object_end fixture + smokes 2025-12-17 23:12:49 +09:00
d42117ac5f test: Phase 107 find_balanced_array_end fixture + smokes 2025-12-17 22:47:42 +09:00
a05ce39a1f test: add Phase104 json_cur read_digits fixture and smokes 2025-12-17 21:25:12 +09:00
e935b2324b test(smokes): dedupe LLVM EXE scripts via llvm_exe_runner 2025-12-17 21:24:59 +09:00
950560a3d9 test(joinir): Phase 104 read_digits loop(true) parity 2025-12-17 18:29:27 +09:00
3fe92312a1 test: Phase 103 P1 if-only early return parity 2025-12-17 17:45:12 +09:00
99e1d24eaf test: Phase 103 if-only merge fixture + VM/LLVM smokes 2025-12-17 17:41:07 +09:00
5b4f9c25e4 test: Phase 102 real-app read_quoted fixture + VM/LLVM smokes 2025-12-17 16:57:11 +09:00
b7a1cc4601 test(smoke): avoid Phase100 string accumulator LLVM EXE skip via plugin cache 2025-12-17 16:38:02 +09:00
dfc01f4dc5 test: Phase 100 string accumulator fixture+smokes (VM+LLVM)
- Add phase100_string_accumulator_min.hako fixture
  * out = out + ch string accumulation
  * print(out.length()) for stable numeric output
- Add VM smoke: phase100_string_accumulator_vm.sh
- Add LLVM EXE smoke: phase100_string_accumulator_llvm_exe.sh (Phase 97 gating)
- Regression: all phase100/97/94 tests pass

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 16:33:26 +09:00
43eda13b01 fix(smoke): Phase 97 LLVM EXE filter debug logs from output
- Filter out debug log lines (starting with '[') before numeric extraction
- grep -v '^\[' excludes debug lines like [UnifiedBoxRegistry], [TRACE]
- Ensures clean numeric output extraction for test validation

Note: Test still fails due to functional bug (returns 0,0,0 instead of 2,-1,3)
This is a separate issue requiring investigation of LLVM backend loop handling

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

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-17 06:40:37 +09:00
cca9ce398e test: Phase 100 mutable accumulator LLVM EXE smoke
- Add phase100_mutable_accumulator_llvm_exe.sh
- Plugin gating via Phase 97 pattern (dlopen cache → build-all)
- Numeric output validation (same SSOT as VM smoke)
- Regression: phase94 pass (phase97 has pre-existing issue)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 06:31:15 +09:00
536e6280c5 test: Phase 100 mutable accumulator fixture + smoke (numeric validation)
- Add apps/tests/phase100_mutable_accumulator_min.hako
  * Pattern2 with break (if i >= 3 { break })
  * Two accumulators: out = out + ch (string), count = count + 1 (integer)
  * print(count) for stable numeric output
- Add phase100_mutable_accumulator_vm.sh smoke test
  * HAKO_JOINIR_STRICT=1 validation
  * Numeric-only output extraction (expected: 3)
- Regression: all phase100/96/94 tests pass

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 06:10:59 +09:00
82806f8f90 test: Phase 100 pinned local receiver fixture + smoke
- Add apps/tests/phase100_pinned_local_receiver_min.hako
  * Dynamic string construction with pinned receiver usage
  * Demonstrates loop-outer local as method receiver
- Add tools/smokes/v2/profiles/integration/apps/phase100_pinned_local_receiver_vm.sh
  * HAKO_JOINIR_STRICT=1 validation
  * Numeric output extraction for log-resistant testing
- Regression: phase96 and phase94 smoke tests pass

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

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-17 05:43:44 +09:00
708d01d1f8 test: Phase 99 add trailing backslash escape best-effort (VM+LLVM)
末尾バックスラッシュ処理:
- 現行仕様: best-effort(そのまま出力)として固定
- fixture: "hello\\" → "hello\" を出力
- VM+LLVM EXE parity完全対応

Integration smokeで検証済み

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 04:26:05 +09:00
b23d23f11f test: Phase 99 extend next_non_ws to 3 cases (VM+LLVM)
3ケース固定:
- 既存: "  hi" → 2, " \t" → -1
- 新規: "\n\r\tX" → 3 (mixed newline/CR/tab)

VM+LLVM EXE parity完全対応

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 04:25:57 +09:00
6d73fc3404 feat(llvm): Phase 97 Box/Policy refactoring complete
Box化完了:
- CallRoutePolicyBox: Call routing SSoT
- PrintArgMarshallerBox: Print marshalling SSoT
- TypeFactsBox: Type propagation SSoT
- PhiSnapshotPolicyBox: PHI contract SSoT
- PluginErrorContext: Structured error reporting

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 04:14:26 +09:00
65763c1ed6 feat(llvm): Phase 97 - Call/PHI/Plugin強化 + リファクタリング準備
## 概要
LLVM backend のCall処理、PHI wiring、Plugin loader を強化。
次のリファクタリング(箱化モジュール化)のための準備も含む。

## 変更内容

### LLVM Call処理強化
- `mir_call/__init__.py`: Call ルーティングロジック改善
- `mir_call/global_call.py`: print処理の marshal強化
- `mir_call/method_call.py`: メソッド呼び出し処理改善
- `boxcall.py`: BoxCall処理改善

### PHI処理強化
- `phi_manager.py`: PHI管理改善
- `phi_wiring/wiring.py`: PHI配線ロジック強化(+17行)
- `phi_wiring/tagging.py`: Type tagging改善
- `resolver.py`: Value解決ロジック強化(+34行)

### Copy伝播
- `copy.py`: Copy命令のType tag伝播追加(+10行)

### Plugin loader強化
- `library.rs`: エラー出力改善、[plugin/missing]ログ追加(+34行)
- fail-fast強化

### テスト
- `phase97_json_loader_escape_llvm_exe.sh`: Phase 97 E2Eテスト追加
- `phase97_next_non_ws_llvm_exe.sh`: Phase 97 E2Eテスト追加

### その他
- `nyash_kernel/lib.rs`: Kernel側の改善(+23行)

## 統計
- 14ファイル変更
- +256行 / -53行 = +203 net

## 次のリファクタリング準備
以下の箇所がリファクタリング対象として識別済み:
1. Call ルーティング箱の明文化
2. print の marshal 箱
3. TypeFacts/Tagging 箱の一本化
4. PHI Snapshot 契約のSSOT
5. Plugin loader のエラー出力統合

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 03:51:03 +09:00
bc55c50d70 test: add Phase 97 LLVM EXE smokes for MiniJsonLoader 2025-12-17 02:26:24 +09:00
bc1a09f2c3 fix(joinir): Phase 96 next_non_ws break condition SSOT 2025-12-17 01:59:21 +09:00
db4453eb3c test: strengthen phase96 next_non_ws fixture 2025-12-17 01:35:43 +09:00
ba87afd35c test: add phase96 trim loop fixture and smoke 2025-12-17 01:25:06 +09:00
1a3e6474c3 test: add phase95 json_loader escape fixture 2025-12-17 01:01:07 +09:00
7ab459503b feat(joinir): Phase 94 - P5b escape full E2E (derived ch + +1/+2) 2025-12-17 00:59:33 +09:00
d2972c1437 feat(joinir): Phase 92完了 - ConditionalStep + body-local変数サポート
## Phase 92全体の成果

**Phase 92 P0-P2**: ConditionalStep JoinIR生成とbody-local変数サポート
- ConditionalStep(条件付きキャリア更新)のJoinIR生成実装
- Body-local変数(ch等)の条件式での参照サポート
- 変数解決優先度: ConditionEnv → LoopBodyLocalEnv

**Phase 92 P3**: BodyLocalPolicyBox + 安全ガード
- BodyLocalPolicyDecision実装(Accept/Reject判定)
- BodyLocalSlot + DualValueRewriter(JoinIR/MIR二重書き込み)
- Fail-Fast契約(Cannot promote LoopBodyLocal検出)

**Phase 92 P4**: E2E固定+回帰最小化 (本コミット)
- Unit test 3本追加(body-local変数解決検証)
- Integration smoke追加(phase92_pattern2_baseline.sh、2ケースPASS)
- P4-E2E-PLAN.md、P4-COMPLETION.md作成

## 主要な実装

### ConditionalStep(条件付きキャリア更新)
- `conditional_step_emitter.rs`: JoinIR Select命令生成
- `loop_with_break_minimal.rs`: ConditionalStep検出と統合
- `loop_with_continue_minimal.rs`: Pattern4対応

### Body-local変数サポート
- `condition_lowerer.rs`: body-local変数解決機能
  - `lower_condition_to_joinir`: body_local_env パラメータ追加
  - 変数解決優先度実装(ConditionEnv優先)
  - Unit test 3本追加: 変数解決/優先度/エラー
- `header_break_lowering.rs`: break条件でbody-local変数参照
- 7ファイルで後方互換ラッパー(lower_condition_to_joinir_no_body_locals)

### Body-local Policy & Safety
- `body_local_policy.rs`: BodyLocalPolicyDecision(Accept/Reject)
- `body_local_slot.rs`: JoinIR/MIR二重書き込み
- `dual_value_rewriter.rs`: ValueId書き換えヘルパー

## テスト体制

### Unit Tests (+3)
- `test_body_local_variable_resolution`: body-local変数解決
- `test_variable_resolution_priority`: 変数解決優先度(ConditionEnv優先)
- `test_undefined_variable_error`: 未定義変数エラー
- 全7テストPASS(cargo test --release condition_lowerer::tests)

### Integration Smoke (+1)
- `phase92_pattern2_baseline.sh`:
  - Case A: loop_min_while.hako (Pattern2 baseline)
  - Case B: phase92_conditional_step_minimal.hako (条件付きインクリメント)
  - 両ケースPASS、integration profileで発見可能

### 退行確認
-  既存Pattern2Breakテスト正常(退行なし)
-  Phase 135 smoke正常(MIR検証PASS)

## アーキテクチャ設計

### 変数解決メカニズム
```rust
// Priority 1: ConditionEnv (loop params, captured)
if let Some(value_id) = env.get(name) { return Ok(value_id); }
// Priority 2: LoopBodyLocalEnv (body-local like `ch`)
if let Some(body_env) = body_local_env {
    if let Some(value_id) = body_env.get(name) { return Ok(value_id); }
}
```

### Fail-Fast契約
- Delta equality check (conditional_step_emitter.rs)
- Variable resolution error messages (ConditionEnv)
- Body-local promotion rejection (BodyLocalPolicyDecision::Reject)

## ドキュメント

- `P4-E2E-PLAN.md`: 3レベルテスト戦略(Level 1-2完了、Level 3延期)
- `P4-COMPLETION.md`: Phase 92完了報告
- `README.md`: Phase 92全体のまとめ

## 将来の拡張(Phase 92スコープ外)

- Body-local promotionシステム拡張
- P5bパターン認識の汎化(flagベース条件サポート)
- 完全なP5b E2Eテスト(body-local promotion実装後)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 21:37:07 +09:00
7e03cb6425 docs(phase-91): Update Phase 91 README with Step 2 completion status
### Updates

#### 1. Status Section
- Updated Status to reflect all completed steps (1, 2-A/B/D, 2-E)
- Documented parity verification success

#### 2. Completion Status Section (NEW)
- Added dedicated section for Phase 91 Step 2 completion
- Listed all deliverables with checkmarks
- Documented test results: 1062/1062 PASS

#### 3. Next Steps
- Clarified Phase 92 lowering requirements
- Updated timeline expectations

#### 4. Test Fixture Fix
- Fixed syntax error in test_pattern5b_escape_minimal.hako
  (field declarations: changed `console: ConsoleBox` to `console ConsoleBox`)

### Context

Phase 91 Step 2 is now fully complete:
-  AST recognizer (detect_escape_skip_pattern)
-  Canonicalizer integration (UpdateKind::ConditionalStep)
-  Unit tests (test_escape_skip_pattern_recognition)
-  Parity verification (strict mode green)

Ready for Phase 92 lowering implementation.

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

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-16 14:55:40 +09:00
9e3b258046 feat(phase-91): JoinIR Selfhost depth-2 advancement - Pattern P5b design & planning
## Overview
Analyzed 34 loops across selfhost codebase to identify JoinIR coverage gaps.
Current readiness: 47% (16/30 loops). Next frontier: Pattern P5b (Escape Handling).

## Current Status
- Phase 91 planning document: Complete
  - Loop inventory across 6 key files
  - Priority ranking: P5b (escape) > P5 (guard) > P6 (nested)
  - Effort estimates and ROI analysis

- Pattern P5b Design: Complete
  - Problem statement (variable-step carriers)
  - Pattern definition with Skeleton layout
  - Recognition algorithm (8-step detection)
  - Capability taxonomy (P5b-specific guards)
  - Lowering strategy (Phase 92 preview)

- Test fixture: Created
  - Minimal escape sequence parser
  - JSON string with backslash escape

- Loop Canonicalizer extended
  - Capability table updated with P5b entries
  - Fail-Fast criteria documented
  - Implementation checklist added

## Key Findings

### Loop Readiness Matrix
| Category | Count | JoinIR Status |
|----------|-------|--------------|
| Pattern 1 (simple bounded) | 16 |  Ready |
| Pattern 2 (with break) | 1 | ⚠️ Partial |
| **Pattern P5b (escape seq)** | ~3 |  NEW |
| Pattern P5 (guard-bounded) | ~2 |  Deferred |
| Pattern P6 (nested loops) | ~8 |  Deferred |

### Top Candidates
1. **P5b**: json_loader.hako:30 (8 lines, high reuse)
   - Effort: 2-3 days (recognition)
   - Impact: Unlocks all escape parsers

2. **P5**: mini_vm_core.hako:541 (204 lines, monolithic)
   - Effort: 1-2 weeks
   - Impact: Major JSON optimization

3. **P6**: seam_inspector.hako:76 (7+ nesting)
   - Effort: 2-3 weeks
   - Impact: Demonstrates nested composition

## Phase 91 Strategy
**Recognition-only phase** (no lowering in P1):
- Step 1: Design & planning 
- Step 2: Canonicalizer implementation (detect_escape_pattern)
- Step 3: Unit tests + parity verification
- Step 4: Lowering deferred to Phase 92

## Files Added
- docs/development/current/main/phases/phase-91/README.md - Full analysis & planning
- docs/development/current/main/design/pattern-p5b-escape-design.md - Technical design
- tools/selfhost/test_pattern5b_escape_minimal.hako - Test fixture

## Files Modified
- docs/development/current/main/design/loop-canonicalizer.md
  - Capability table extended with P5b entries
  - Pattern P5b full section added
  - Implementation checklist updated

## Acceptance Criteria (Phase 91 Step 1)
-  Loop inventory complete (34 loops across 6 files)
-  Pattern P5b design document ready
-  Test fixture created
-  Capability taxonomy extended
-  Implementation deferred (Step 2+)

## References
- JoinIR Architecture: joinir-architecture-overview.md
- Phase 91 Plan: phases/phase-91/README.md
- P5b Design: design/pattern-p5b-escape-design.md

Next: Implement detect_escape_pattern() recognition in Phase 91 Step 2

🤖 Generated with Claude Code

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-16 14:22:36 +09:00
2674e074b6 feat(joinir): Phase 142 P2 Step 3-A - Pattern4 early return fail-fast 2025-12-16 13:48:30 +09:00
22b0c14adb feat(joinir): Phase 135 P1 - Contract checks Fail-Fast (二度と破れない設計)
## Summary
Adds early Fail-Fast contract verification to prevent Phase 135 P0 issues from recurring.
Two new verifiers catch allocator SSOT violations and boundary inconsistencies before --verify.

## Changes

### Step 1: verify_condition_bindings_consistent
**Location**: `src/mir/builder/control_flow/joinir/merge/contract_checks.rs`

**Contract**: condition_bindings can have aliases (multiple names for same join_value),
but same join_value with different host_value is a violation.

**Example Error**:
```
[JoinIRVerifier/Phase135-P1] condition_bindings conflict:
  join_value ValueId(104) mapped to both ValueId(12) and ValueId(18)
```

**Catches**: ConditionLoweringBox bypassing SSOT allocator before BoundaryInjector

### Step 2: verify_header_phi_dsts_not_redefined
**Location**: `src/mir/builder/control_flow/joinir/merge/contract_checks.rs`

**Contract**: Loop header PHI dst ValueIds must not be reused as dst in non-PHI instructions.
Violation breaks MIR SSA (PHI dst overwrite).

**Example Error**:
```
[JoinIRVerifier/Phase135-P1] Header PHI dst ValueId(14) redefined by non-PHI instruction in block 3:
  Instruction: Call { dst: Some(ValueId(14)), ... }
```

**Catches**: ValueId collisions between header PHI dsts and lowered instructions

### Integration
**Location**: `src/mir/builder/control_flow/joinir/merge/mod.rs`

Added to `verify_joinir_contracts()`:
1. Step 1 runs before merge (validates boundary)
2. Step 2 runs after merge (validates func with PHI dst set)

### Documentation
- Updated `phase135_trim_mir_verify.sh` - Added P1 contract_checks description
- Updated `phase-135/README.md` - Added P1 section with contract details and effects

## Acceptance
 Build: SUCCESS
 Smoke: phase135_trim_mir_verify.sh - PASS
 Regression: phase132_exit_phi_parity.sh - 3/3 PASS
 Regression: phase133_json_skip_whitespace_llvm_exe.sh - PASS

## Effect
- **Prevention**: Future Box implementations catch SSOT violations immediately
- **Explicit Errors**: Phase 135-specific messages instead of generic --verify failures
- **Unbreakable**: Debug builds always detect violations, enforced by CI/CD

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-15 19:25:33 +09:00
d82c332a40 feat(joinir): Phase 135 P0 - ConditionLoweringBox allocator SSOT (ValueId collision fix)
## Summary
Root cause: ConditionLoweringBox was bypassing ConditionContext.alloc_value (SSOT allocator),
causing ValueId collisions between JoinIR condition params and lowered instructions.

## Changes
1. **ConditionLoweringBox (expr_lowerer.rs)**: Must use ConditionContext.alloc_value
   - Pass &mut ConditionContext to lower_condition (SSOT allocator)
   - Eliminates internal counter usage

2. **Allocator unification (condition_lowerer.rs, method_call_lowerer.rs)**:
   - Accept &mut dyn FnMut() -> ValueId as allocator parameter
   - Ensures all lowering paths use same SSOT allocator

3. **Boundary Copy deduplication (joinir_inline_boundary_injector.rs)**:
   - Deduplicate condition_bindings by dst
   - Fail-Fast if different sources target same dst (MIR SSA violation)

4. **Trim pattern fixes (trim_loop_lowering.rs, trim_pattern_validator.rs, stmts.rs)**:
   - Use builder.next_value_id() instead of value_gen.next() in function context
   - Ensures function-level ValueId allocation respects reserved PHI dsts

## Acceptance
 ./target/release/hakorune --verify apps/tests/phase133_json_skip_whitespace_min.hako
 Smoke: phase135_trim_mir_verify.sh - MIR SSA validation PASS
 Regression: phase132_exit_phi_parity.sh - 3/3 PASS
 Regression: phase133_json_skip_whitespace_llvm_exe.sh - compile-only PASS

🤖 Generated with Claude Code

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-15 18:49:08 +09:00
e8e4779942 feat(plugin): Phase 134 P1 - Core box strict guard (SSOT in plugin_guard.rs) 2025-12-15 17:49:08 +09:00
ccd2342376 feat(plugin_loader): Phase 134 P0 - Best-effort plugin loading (continue on failures) 2025-12-15 17:00:51 +09:00
06bfb1eb31 test(docs): Phase 133 smoke is compile-only (--dump-mir) 2025-12-15 16:57:28 +09:00
6bade8607e test: Phase 133 P0 - Promoted carrier join_id smoke test (JsonParser pattern) 2025-12-15 12:36:25 +09:00
aad01a1079 feat(llvm): Phase 132-P2 - Dict ctx removal (FunctionLowerContext SSOT completion)
Completed SSOT unification for FunctionLowerContext by removing the manual
dict ctx creation and assignment in function_lower.py.

Changes:
- Removed builder.ctx = dict(...) creation (18 lines, lines 313-330)
- Removed builder.resolver.ctx assignment (no longer needed)
- Confirmed instruction_lower.py uses context=owner.context throughout
- Added phase132_multifunc_isolation_min.hako test for multi-function isolation
- Extended phase132_exit_phi_parity.sh with Case C (Rust VM context test)

Testing:
- Phase 132 smoke test: All 3 cases PASS
- Phase 87 LLVM exe test: PASS (Result: 42)
- STRICT mode: PASS
- No regressions: Behavior identical before/after (RC:6 maintained)

Impact:
- Reduced manual context management complexity
- FunctionLowerContext now sole source of truth (SSOT)
- Per-function state properly isolated, no cross-function collisions
- Cleaner architecture: context parameter passed explicitly vs manual dict

🤖 Generated with Claude Code
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-15 12:12:54 +09:00
42f7eaa215 tools: speed up build_llvm NyRT cache + fix Phase 132 smoke counters
Improvements:
1. NyRT build cache in tools/build_llvm.sh
   - Skip [3/4] rebuild when target/release/libnyash_kernel.a exists
   - Add NYASH_LLVM_FORCE_NYRT_BUILD env var to force rebuild
   - Performance: 60-80% faster on incremental builds

2. Fix Phase 132 smoke test arithmetic bug
   - Replace ((PASS_COUNT++)) with PASS_COUNT=$((PASS_COUNT + 1))
   - Issue: ((x++)) returns 0 when x=0, causes set -e to exit
   - Locations: 8 places in phase132_exit_phi_parity.sh

3. Document NYASH_LLVM_FORCE_NYRT_BUILD in environment-variables.md

Acceptance criteria met:
- Behavior unchanged (first build creates .a, subsequent skip rebuild)
- NYASH_LLVM_FORCE_NYRT_BUILD allows forcing rebuild
- Phase 132 smoke test passes (both cases)
- Behavior-preserving optimization

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

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-15 11:06:26 +09:00