84d63ac11b
docs: Phase 119 StepTree cond SSOT (AST handle)
2025-12-18 04:03:50 +09:00
052040e59c
refactor(joinir): extract ExitArgsCollectorBox for jump_args SSOT
...
Phase 118 refactoring: Box modularization for exit value collection.
# Changes
- Created `exit_args_collector.rs` with ExitArgsCollectorBox
- Extracted jump_args processing logic from instruction_rewriter.rs
- Implemented SSOT for offset calculation (0 vs 1 legacy layout)
- Added comprehensive unit tests (6 tests, all passing)
# Design
- **Responsibility**: Collects exit PHI inputs + carrier inputs from jump_args
- **SSOT**: Centralized offset calculation logic
- **Fail-Fast**: Validates jump_args length against exit_bindings
- **Phase 118 P2 Contract**: Uses boundary.exit_bindings as SSOT
# Key Features
- Filters ConditionOnly carriers (no exit PHI needed)
- Handles both direct mapping (offset=0) and legacy layout (offset=1)
- Strict mode: Fail-Fast on validation errors
- Non-strict mode: Warns and continues with best effort
# Test Results
- Unit tests: 6/6 PASS
- Phase 118 smoke tests: PASS (VM + LLVM)
- Phase 117 regression: PASS
# Reduced Code Complexity
- instruction_rewriter.rs: ~90 lines → ~25 lines (box call)
- Offset logic: Centralized in ExitArgsCollectorBox
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-18 03:56:21 +09:00
432fc96082
refactor(joinir): extract IfSumExitMetaBuilderBox for Fail-Fast carrier binding
...
Phase 118 refactoring: Box modularization for ExitMeta generation.
# Changes
- Created `exit_meta_builder.rs` with IfSumExitMetaBuilderBox
- Extracted ExitMeta generation logic from loop_with_if_phi_if_sum.rs
- Implemented Fail-Fast contract (carrier name validation)
- Added comprehensive unit tests (5 tests, all passing)
# Design
- **Responsibility**: Builds ExitMeta from carrier name + ValueId
- **Fail-Fast**: Validates carrier names immediately
- **Reusability**: Can be used by other patterns (Pattern 4, etc.)
# Test Results
- Unit tests: 5/5 PASS
- Phase 118 smoke tests: PASS (VM + LLVM)
- Phase 117 regression: PASS
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-18 03:56:10 +09:00
5091cda9cb
docs: Phase 118 DONE (loop+if merge parity)
2025-12-18 03:43:16 +09:00
8fb393b5e8
test(joinir): Phase 118 loop+if merge parity smokes
2025-12-18 03:43:10 +09:00
1080dee58f
fix(joinir): Phase 118 Pattern3 exit carrier PHI SSOT
2025-12-18 03:43:00 +09:00
2c7f5f7a5e
docs: Phase 117 DONE
...
Phase 117: if-only nested-if + call merge parity completed.
**Documentation**:
- docs/development/current/main/phases/phase-117/README.md (complete)
- docs/development/current/main/10-Now.md (updated with Phase 117 entry)
- docs/development/current/main/01-JoinIR-Selfhost-INDEX.md (added Phase 117 to index)
**Phase 117 Summary**:
- Verified nested if-only (inner if + outer else) with call merge
- Pattern: 3 call sites (f(1), f(2), f(3)) merge to single variable
- VM/LLVM EXE parity: both produce identical output "2\n3\n4"
- Regression: Phase 116 maintained
**Technical Details**:
- JoinIR Pattern3 (if-only) nested structure validation
- Call merge across nested control flow
- PHI node generation for nested branches
- LLVM EXE plugin integration (StringBox, IntegerBox, ConsoleBox)
**Next Steps**:
Phase 118+ will address more complex nested patterns (if-else nested, loop-if combinations).
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-18 02:55:14 +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
f63b5c3c64
docs: fix INDEX numbering + refresh backlog after Phase 116
...
- Fixed INDEX numbering: 24/25 → 28/29 (was duplicated after Phase 116 additions)
- Updated Backlog: next candidate Phase 114 → Phase 117 (nested if + call merge)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-18 02:52:01 +09:00
8440550b2f
docs: Phase 116 DONE
...
Phase 116 完了ドキュメント化
## 更新内容
### Phase 116 README
- 背景: LLVM fragile pattern(keep+call merge)
- 実装内容: fixture, VM smoke, LLVM EXE smoke
- 検証コマンド
- 技術的詳細: JoinIR Pattern 1, PHI接続
- Lessons Learned: Box-First原則, Fail-Fast原則
### 10-Now.md
- Phase 116 完了エントリ追加
- 入口: `docs/development/current/main/phases/phase-116/README.md`
### 01-JoinIR-Selfhost-INDEX.md
- Phase 116 を JoinIR Phase リストに追加
- 番号の重複を修正(18-27に整理)
## 成果物
✅ 片側元値保持、片側call結果のmergeパターンをVM/LLVM両方で固定
✅ output_validator.sh, llvm_exe_runner.sh 活用で統一的なテスト基盤
✅ 回帰防止: Phase 115 維持確認
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-18 02:39:44 +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
97675b4035
docs: Phase 114 DONE
...
Phase 114完了に伴うドキュメント更新:
- 30-Backlog.md: Phase 114の次候補から完了済みに移行
- design/control-tree.md: Phase 110-112の進捗反映
- design/README.md, joinir-design-map.md, phases/README.md: マイナー更新
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-18 02:19:41 +09:00
ce7e2c1b91
refactor(env): centralize NYASH_JOINIR_STRUCTURE_ONLY flag
...
Moved NYASH_JOINIR_STRUCTURE_ONLY environment variable handling
from inline std::env::var() in routing.rs to a centralized helper
function in src/config/env/joinir_flags.rs.
Changes:
- Added joinir_structure_only_enabled() helper function
- Replaced direct env::var() call in routing.rs with helper
- Maintains existing behavior: default ON, NYASH_JOINIR_STRUCTURE_ONLY=0/off to disable
- Follows env module centralization pattern (Box Theory: separation of concerns)
Testing:
- cargo test --lib: 1126 passed ✅
- Regression: Phase 107 VM smoke ✅
- Phase 113/114 maintained ✅
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-18 02:19:14 +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
70fe0da549
docs: Phase 113 if-only partial assign parity
...
- Create phases/phase-113/README.md (background, fixed pattern, verification)
- Update 10-Now.md with Phase 113 completion
- Update 01-JoinIR-Selfhost-INDEX.md with Phase 113 entry
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-18 01:58:56 +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
7829b23cf4
docs: note Phase 110-112 control_tree status
...
- Update 10-Now.md with Phase 112 completion
- Note: StepTree capability guard (strict-only) implemented
- Note: Default behavior unchanged, only affects 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 01:39:06 +09:00
09ce24e132
feat(joinir): Phase 112 strict guard for StepTree required_caps
...
- Add control_tree_capability_guard.rs with check(tree, func_name, strict, dev)
- Allowlist: If, NestedIf, Loop, Return, Break, Continue
- Deny (strict): NestedLoop, TryCatch, Throw, Lambda, While, ForRange, Match, Arrow
- Wire into lower_function_body() (strict-only check)
- Error format: [joinir/control_tree/cap_missing/<Cap>] with 1-line Hint
- Unit tests: nested_loop_rejects, if_only_passes, strict_false_passes
- Default behavior unchanged (strict=false always Ok)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-18 01:38:25 +09:00
14730c227f
feat(control_tree): add StepTreeContract and signature (dev-only)
2025-12-18 00:57:58 +09:00
9bcda215f8
refactor(joinir): split Pattern2 orchestrator into smaller steps
2025-12-18 00:44:31 +09:00
e4735f4054
refactor(control_tree): use ASTNode::span SSOT
2025-12-18 00:32:23 +09:00
67a2408da5
docs: clarify StepTree boundary (no routing)
2025-12-18 00:30:04 +09:00
3987aa5b06
refactor(joinir): drop unused break helper wrappers
2025-12-18 00:30:01 +09:00
e65bb791b9
refactor(builder): route debug logs via trace
2025-12-18 00:29:57 +09:00
2b5c141e22
feat(control_tree): add StepTree builder (dev-only)
2025-12-18 00:22:21 +09:00
b32480823d
docs: add ControlTree/StepTree SSOT
2025-12-18 00:14:04 +09:00
a27e3ce908
docs: Phase 109 DONE
...
- Create phases/phase-109/README.md
- Update 10-Now.md with completion report
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-17 23:45:55 +09:00
a9f92f8f1a
refactor(joinir): add hints for Phase107/104/100 policy rejects
...
- balanced_depth_scan: missing_tail_inc, missing_return_i hints
- read_digits: missing_eos_guard, digit_set_mismatch hints
- pinned: missing_host_id hint
- Gradual migration (representative cases only)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-17 23:45:49 +09:00
2ab460f0a8
feat(joinir): error_tags freeze_with_hint
...
- Add freeze_with_hint(tag, msg, hint) API
- Format: "[joinir/<tag>] <msg> Hint: <hint>"
- Panic on empty hint (must provide actionable suggestion)
- Keep existing freeze() for backward compatibility
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-17 23:45:40 +09:00
23e7f4629f
docs: Phase 109 plan (error_tags hints SSOT)
...
- Add hint policy to joinir-design-map.md
- Document format: [joinir/<category>/<tag>] <msg> Hint: <hint>
- Establish SSOT for error messages
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com >
2025-12-17 23:45:32 +09:00
46c924ac6d
docs: add Phase 108 entry
2025-12-17 23:30:13 +09:00
27e8e0f16a
refactor(joinir): Phase 108 unify Pattern2 policy routing
2025-12-17 23:30:08 +09:00
9fa2f5a8ad
test: align Phase 107 object fixture expected output
2025-12-17 23:16:53 +09:00
6a21382d44
docs: add Phase 107 to Now/INDEX and backlog
2025-12-17 23:15:57 +09:00
3c934dc69d
test: Phase 107 add find_balanced_object_end fixture + smokes
2025-12-17 23:12:49 +09:00
3c1d8a824d
feat(joinir): extend balanced depth-scan policy to object family
2025-12-17 23:09:19 +09:00
09dd10349f
refactor(joinir): make Pattern2 body-local handling policy-driven
2025-12-17 23:00:26 +09:00
10a2f3b48b
refactor(joinir): centralize balanced depth-scan policy decision
2025-12-17 22:59:27 +09:00
6036627920
fix(joinir): avoid false rejects in balanced depth-scan policy
2025-12-17 22:52:29 +09:00
d42117ac5f
test: Phase 107 find_balanced_array_end fixture + smokes
2025-12-17 22:47:42 +09:00
d8ce9fdb99
fix(joinir): wire balanced depth-scan policy through Pattern2
2025-12-17 22:47:36 +09:00
9ec2e28b6a
feat(joinir): add Pattern2 post-loop early return step
2025-12-17 22:32:55 +09:00
aa29dc8085
feat(joinir): emit balanced depth-scan derived vars
2025-12-17 22:32:50 +09:00
bf80789757
feat(joinir): route balanced depth-scan via Pattern2 policy
2025-12-17 22:32:43 +09:00
f1a570fd45
feat(joinir): Phase 107 balanced depth-scan policy (analysis-only)
2025-12-17 22:25:34 +09:00
97c65a9e6f
docs: Phase 107 plan (find_balanced_array_end)
2025-12-17 22:21:42 +09:00
af3b851984
docs: add Phase 107 prep for find_balanced
2025-12-17 22:01:23 +09:00
5f4d8ba112
refactor(joinir): Phase 106 Pattern2 step boxes
2025-12-17 22:01:19 +09:00