feat(stageb): Phase 25.1c - Stage-B トレース追加(dev-only)

追加内容:
- StageBTraceBox: dev トレース用 Box 追加(HAKO_STAGEB_TRACE=1 で有効)
- トレースポイント:
  - StageBArgsBox.resolve_src: enter/return_len
  - StageBBodyExtractorBox.build_body_src: enter_len/return_len
  - StageBDriverBox.main: enter/after_resolve_src/after_build_body_src/
    after_parse_program2/func_scan methods/exit rc=0

Phase 25.1c 目標:
- Stage-B / Stage-1 CLI 構造デバッグ
- fib canary / selfhost CLI canary の rc=1 原因特定

ポリシー:
- dev env でガード(挙動不変)
- 既定挙動は変更せず、観測のみ追加

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-11-19 04:49:25 +09:00
parent 5c5e1bd099
commit fa571a656e
5 changed files with 193 additions and 7 deletions

View File

@ -85,3 +85,38 @@ Status: planning構造整理フェーズ・挙動は変えない
- Phase 25.1b: selfhost builder / multicarrier / BoxTypeInspector 実装フェーズ(機能側)。
- Phase 25.1c: そのうち「env.* / hostbridge.* / BoxIntrospect」に加えて、StageB Main / LoopBuilder / builder 観測レイヤの構造と責務も整理するメタフェーズ(構造側)。
- 挙動を変えないことFailFast / default path は現状維持)を前提に、小さな差分で進める。
### デバッグ方針25.1c で踏みたい順番)
- 1) StageB rc=1 の発生箇所を箱単位まで特定する
- 代表 canary:
- `tools/smokes/v2/profiles/quick/core/phase251/stageb_fib_program_defs_canary_vm.sh`
- `tools/smokes/v2/profiles/quick/core/phase251/selfhost_cli_run_basic_vm.sh`
- まずは `compiler_stageb.hako` の流れを箱ごとに分解してログする:
- `StageBArgsBox.resolve_src`
- `StageBBodyExtractorBox.build_body_src`
- `ParserBox.parse_program2`
- `FuncScannerBox.scan_all_boxes`
- 各箱の入口/出口に `[stageb/trace:<box>.<method>:enter|leave]` のような軽いタグを置き、どの箱が rc=1 の直前で止まっているかを特定する(挙動は変えない)。
- 2) Rust Region レイヤを「正解ビュー」として .hako 側を寄せる
- Rust 側にはすでに `Region / RefSlotKind / FunctionSlotRegistry + ControlForm` があり、`StageBBodyExtractorBox.*` 周辺のスロット(`src/body_src/bundle_*` など)がどの Loop/If Region に属しているかを `NYASH_REGION_TRACE=1` で観測できる。
- 25.1c では .hako 側に観測専用 Box案: `StageBRegionObserverBox`)を追加し、
- `enter_region(kind, name, slots_json)`
- `leave_region()`
のような API で「箱名・構造名・スロット名の集合」だけを JSON で print する。
- `StageBBodyExtractorBox` の外側ループ・内側 if など、問題になりやすい箇所でこの Box を呼び出し、Rust の `[region/observe]` ログと「木構造+スロット名」が対応しているかを確認する。
→ ずれている Region例: `body_src` などが早期に欠落するスコープ)から優先的に修正する。
- 3) StageB 用の極小ハーネスを Rust / .hako 両方に用意する
- fib canary はやや重いため、100〜200 行程度の「using + 1 box + 1 loop」だけの最小サンプルを `lang/src/compiler/tests/stageb_min_sample.hako` のようなファイルとして固定する。
- Rust 側:
- そのサンプルを AST→MIR に通し、`NYASH_VM_VERIFY_MIR=1``Undefined value` が出ないことを確認する小さなテストを用意(既存の StageB 向け MIR テスト群に揃える)。
- .hako 側:
- 同じサンプルを入力として `StageBDriverBox` の簡易版mini driverを作り、`StageBArgsBox.resolve_src``StageBBodyExtractorBox.build_body_src``ParserBox.parse_program2` だけを通す driver を追加する。
- これにより、StageB/LoopBuilder に対する修正を「本番 compiler_stageb.hako 全体」ではなく「ミニマムな Hako 断片」で検証できるようにする。
- 4) Stage1 CLI (`HakoCli.run`) の selfhost ラインは StageB が緑になってから扱う
- `selfhost_cli_run_basic_vm.sh` の現状の失敗は、StageB が rc=1 で Program(JSON) を 1 行も返していないことが原因であり、HakoCli.run の MIR 生成まで到達していない。
- 25.1c ではまず StageB 側fib defs / stageb_min / mini driverを rc=0 に戻し、
その Program(JSON v0) を固定入力にして Phase 25.1b 側の selfhost builder / HakoCli.run MIR を Rust ラインと diff する、という順番で進める。