feat(box_factory): Phase 86 BoxFactory Priority normalization

Phase 86: BoxFactory Priority 正常化プロジェクト完了

目的:
- BoxFactory のデフォルトポリシーを BuiltinFirst から StrictPluginFirst に変更
- プラグイン版 StringBox/ArrayBox/MapBox が正常に使用できるよう正常化
- Phase 85 (Ring0/Ring1-Core 境界設計) の土台準備

実装内容:
1. ドキュメント作成
   - docs/development/current/main/factory_priority.md: 完全仕様文書化

2. コード修正 (1行のみ)
   - UnifiedBoxRegistry::new() が with_env_policy() を使用
   - デフォルトポリシーが StrictPluginFirst に変更

3. テスト追加 (5件, 全パス)
   - test_default_policy_is_strict_plugin_first: デフォルトポリシー確認
   - test_env_policy_override: 環境変数制御確認
   - test_reserved_type_protection: 予約型保護動作確認
   - test_plugin_override_with_env: 予約型 override 確認
   - test_non_reserved_plugin_priority: 非予約型プラグイン優先確認

効果:
-  プラグイン版 StringBox/ArrayBox/MapBox が正常に使用可能
-  core_required Box の予約名保護維持
-  環境変数による柔軟な制御が可能
-  テスト改善: 500→506 passed, 34→33 failed (+6 passed, -1 failed)

core_required Box リスト (暫定):
- Core value types: StringBox, IntegerBox, BoolBox, FloatBox, NullBox
- Core containers: ArrayBox, MapBox, ResultBox
- Core method indirection: MethodBox

環境変数:
- NYASH_BOX_FACTORY_POLICY: ポリシー選択 (default: strict_plugin_first)
- NYASH_USE_PLUGIN_BUILTINS: core_required override 許可
- NYASH_PLUGIN_OVERRIDE_TYPES: 個別 Box override 許可

Phase 85 準備:
- Ring0/Ring1-Core 境界設計の土台が整った
- ConsoleBox の扱いは Phase 85 で最終決定

完了条件:
-  factory_priority.md 作成完了
-  UnifiedBoxRegistry::new() 修正完了
-  デフォルトポリシー StrictPluginFirst 確定
-  テスト 5件追加・全パス
-  CURRENT_TASK.md 更新完了
-  Phase 85 README 準備完了

参考:
- 設計文書: docs/development/current/main/factory_priority.md
- Phase 85 計画: docs/private/roadmap2/phases/phase-85-ring0-runtime/README.md

🎉 Phase 86 完了!次は Phase 85 で Ring0/Ring1-Core 境界の文書化へ
This commit is contained in:
nyash-codex
2025-12-02 21:52:18 +09:00
parent 7dbe0a682c
commit 268a56fdfe
4 changed files with 530 additions and 2 deletions

View File

@ -0,0 +1,237 @@
# BoxFactory Priority 問題と解決策
## 現状の問題
### FactoryPolicy の種類
| ポリシー | 優先順位 | 状態 |
|---------|---------|------|
| `StrictPluginFirst` | Plugin > User > Builtin | 理想(実装済・未使用) |
| `CompatPluginFirst` | Plugin > Builtin > User | 互換(実装済・未使用) |
| `BuiltinFirst` | Builtin > User > Plugin | **現デフォルト(問題)** |
### 問題の詳細
**場所**: `src/box_factory/mod.rs::UnifiedBoxRegistry::new()`
```rust
// 現在の実装(問題)- Line 120-122
impl UnifiedBoxRegistry {
pub fn new() -> Self {
Self::with_policy(FactoryPolicy::BuiltinFirst) // ← ここが問題
}
}
```
**影響**:
- プラグイン版 StringBox が無視される
- プラグイン版 ArrayBox が無視される
- プラグイン版 MapBox が無視される
- Phase 15.5 で特定された優先度問題の根本原因
**環境変数による回避**:
```bash
NYASH_BOX_FACTORY_POLICY=strict_plugin_first ./target/release/nyash program.hako
```
しかし、これは一時的な回避策であり、デフォルト動作が間違っている。
### 既存の実装状況
**良いニュース**: `with_env_policy()` は既に実装済みLine 134-146
```rust
pub fn with_env_policy() -> Self {
let policy = match std::env::var("NYASH_BOX_FACTORY_POLICY").ok().as_deref() {
Some("compat_plugin_first") => FactoryPolicy::CompatPluginFirst,
Some("builtin_first") => FactoryPolicy::BuiltinFirst,
Some("strict_plugin_first") | _ => FactoryPolicy::StrictPluginFirst, // Plugin First DEFAULT!
};
eprintln!(
"[UnifiedBoxRegistry] 🎯 Factory Policy: {:?} (Phase 15.5: Everything is Plugin!)",
policy
);
Self::with_policy(policy)
}
```
**問題**: `new()``with_env_policy()` を呼ばず、ハードコードされた `BuiltinFirst` を使用。
### is_reserved_type() の実装状況
**場所**: `src/box_factory/mod.rs` Line 176-194rebuild_cache内のローカル関数
**現在の core_required リスト**:
- StringBox
- IntegerBox
- BoolBox
- FloatBox
- NullBox
- ArrayBox
- MapBox
- ResultBox
- MethodBox
**環境変数サポート**:
- `NYASH_USE_PLUGIN_BUILTINS=1`: 予約型保護を解除(既に実装済み)
- `NYASH_PLUGIN_OVERRIDE_TYPES=Type1,Type2`: 個別指定(既に実装済み)
---
## Phase 86 の目標ポリシー
### 基本方針
| Box 種別 | ポリシー | 環境変数 override |
|---------|---------|------------------|
| **core_required** | Builtin 固定(予約名) | `NYASH_USE_PLUGIN_BUILTINS=1` で可 |
| **それ以外** | Plugin が Builtin override 可 | デフォルト動作 |
| **BuiltinFirst** | Legacy 専用(非推奨) | CI/古いプロファイルのみ |
### core_required Box リスト
Phase 85 調査結果および既存実装より:
**Core value types**:
- StringBox
- IntegerBox
- BoolBox
- FloatBox
- NullBox
**Core containers and result**:
- ArrayBox
- MapBox
- ResultBox
**Core method indirection**:
- MethodBox
**ConsoleBox の扱い**:
- Phase 85 調査では core_required とされたが、現在の `is_reserved_type()` には含まれていない
- Phase 86 では既存実装を尊重し、ConsoleBox を予約型に追加しない
- 将来的に必要であれば Phase 85 で再検討
これらは `is_reserved_type()` で保護される(既に実装済み)。
### デフォルトポリシー
**新デフォルト**: `StrictPluginFirst`
**理由**:
1. ✅ プラグインによる拡張を優先Nyash の設計思想)
2. ✅ core_required は予約名保護で安全性を確保
3. ✅ 開発者の期待に合致(プラグインが優先されるべき)
4. ✅ "Everything is Plugin" 哲学の体現
### 環境変数
| 環境変数 | 用途 | デフォルト値 |
|---------|------|------------|
| `NYASH_BOX_FACTORY_POLICY` | ポリシー選択 | `strict_plugin_first` |
| `NYASH_USE_PLUGIN_BUILTINS` | core_required override 許可 | 未設定(無効) |
| `NYASH_PLUGIN_OVERRIDE_TYPES` | 個別 Box override 許可 | 未設定(空) |
**使用例**:
```bash
# core_required もプラグイン版を使用(開発用)
NYASH_USE_PLUGIN_BUILTINS=1 ./target/release/nyash program.hako
# 特定 Box のみプラグイン版を使用
NYASH_PLUGIN_OVERRIDE_TYPES=StringBox,ArrayBox ./target/release/nyash program.hako
# Legacy モード(古いテスト用)
NYASH_BOX_FACTORY_POLICY=builtin_first ./target/release/nyash program.hako
```
---
## Phase 86 実装内容
### 修正箇所
**1つの修正のみ**: `UnifiedBoxRegistry::new()` を変更
```rust
// Before (Line 120-122)
impl UnifiedBoxRegistry {
pub fn new() -> Self {
Self::with_policy(FactoryPolicy::BuiltinFirst)
}
}
// After
impl UnifiedBoxRegistry {
pub fn new() -> Self {
Self::with_env_policy() // with_env_policy() を使用
}
}
```
**変更理由**:
- `with_env_policy()` は既に完全実装済みLine 134-146
- デフォルトで `StrictPluginFirst` を返す
- 環境変数 `NYASH_BOX_FACTORY_POLICY` による制御も完全対応
- `is_reserved_type()` による保護も実装済み
- 追加実装は不要!
### 追加実装は不要
以下の機能は既に実装済み:
-`with_env_policy()` の実装Line 134-146
-`is_reserved_type()` の実装Line 176-194
- ✅ 環境変数 `NYASH_USE_PLUGIN_BUILTINS` のサポートLine 178-184
- ✅ 環境変数 `NYASH_PLUGIN_OVERRIDE_TYPES` のサポートLine 179-183
- ✅ Policy-based priority orderingLine 224-256
**Phase 86 の本質**:
- デフォルト動作を正常化する1行の変更
- 既存の完全実装を活用する
- テストで検証する
---
## テスト戦略
### 追加するテスト5件
**ファイル**: `src/box_factory/mod.rs``#[cfg(test)] mod tests` セクション
1. **test_default_policy_is_strict_plugin_first**
- `new()` のデフォルトポリシーを確認
2. **test_env_policy_override**
- 環境変数 `NYASH_BOX_FACTORY_POLICY` の動作確認
3. **test_reserved_type_protection**
- 予約型が非 builtin factory で登録されないことを確認
4. **test_plugin_override_with_env**
- `NYASH_USE_PLUGIN_BUILTINS=1` での予約型 override を確認
5. **test_non_reserved_plugin_priority**
- 非予約型FileBox等が plugin で override できることを確認
---
## 完了条件
-`docs/development/current/main/factory_priority.md` 作成完了
-`UnifiedBoxRegistry::new()``with_env_policy()` を使用
- ✅ デフォルトポリシーが `StrictPluginFirst`
-`is_reserved_type()` が Phase 85 の core_required リストと一致(既存実装確認)
- ✅ テスト 5件追加・全パス
-`CURRENT_TASK.md` 更新完了
- ✅ Phase 85 README 準備完了
---
## 次のステップPhase 85
Phase 86 完了後、Phase 85 で以下を実施:
- Ring0/Ring1-Core 境界の文書化
- core_required Box の最終確定
- ConsoleBox の扱いの再検討
Phase 86 は Phase 85 の土台を安定させるための準備フェーズ。

View File

@ -0,0 +1,62 @@
# Ring0 Inventory初回棚卸しメモ
このドキュメントは、Phase 85-ring0-runtime のための「Ring0 候補呼び出し」の棚卸しメモだよ。
ここでは Task 調査で分かった概況だけをまとめておき、詳細な一覧化や移行は後続フェーズで扱う。
---
## 1. println!/eprintln! 呼び出し
- `println!` / `eprintln!` の合計呼び出し回数: **3,955 回**
- デバッグログ/一時ログ/ユーザ向けメッセージが混在している。
- Ring0 の `LogApi` / `Console` 相当として、最優先で整理したい対象。
- 方針メモ:
- 将来的には `Ring0Context.log` / `Ring0Context.io` 経由に寄せる。
- 代表パスselfhost/hack_check/VM/LLVM`println!/eprintln!` から段階的に移行する。
---
## 2. Box / プラグイン / カーネル実装の数
- `src/boxes`: 34 Box
- `plugins/`: 22 プラグイン
- `crates/nyash_kernel`: 12 カーネル実装
ざっくり分類案Phase 85 時点の暫定):
- core_required:
- StringBox, IntegerBox, BoolBox, ArrayBox, MapBox, ConsoleBox など、言語の基本型+コンソール。
- core_optional:
- FileBox, PathBox, RegexBox, MathBox, TimeBox, JsonBox, TomlBox など、標準ユーティリティ系。
- selfhost_required:
- Stage1CliBox, AotCompilerBox, MirJsonBuilderBox など、selfhost/Stage1 ライン専用。
- user_plugin:
- P2P, HTTP, GUI, Python 連携 等の外部拡張。
※ 正確な一覧とファイルパスは、後続フェーズで Box 定義ファイルを機械的に列挙して作る。
---
## 3. Factory Priority 問題Phase 15.5 の再確認)
- 現状の Factory Priority が `BuiltinFirst`(ビルトイン優先)となっている箇所があり、
- プラグインで上書きしたいケースでも、ビルトイン版が優先されてしまう。
- これは:
- 「core_required な Box」と「user_plugin を使って差し替えたい Box」の境界が曖昧なことの副作用でもある。
- 方針メモ:
- Ring1-core の整理と合わせて、Factory Priority を
- core_required は常にビルトイン
- core_optional / user_plugin は設定やプロファイルで切り替え可能
に整理していく。
---
## 4. 今後の棚卸しタスクTODO メモ)
- `std::fs` / `File::open` / `std::io::stdin` などの呼び出し地点を一覧化。
- `SystemTime::now` / `Instant::now` / `thread::sleep` など時間・スレッド系 API の呼び出し地点を一覧化。
- hakmem / nyrt 経由の低レベル API 呼び出しalloc/free など)を一覧化。
- 代表パスselfhost/hack_check/VM/LLVMのみを対象にした「最小 Ring0 呼び出しセット」を定義する。
これらは Phase 8687 で Ring0Context に寄せていくための下準備だよ。