docs: restore docs/private/roadmap from 7b4908f9 (Phase 20.31)

This commit is contained in:
nyash-codex
2025-10-31 18:00:10 +09:00
parent 1d49e24bf0
commit 8fd3a2b509
433 changed files with 108935 additions and 0 deletions

View File

@ -0,0 +1,193 @@
# Design - 設計ドキュメント
## 📋 概要
Python-Hakorune統合の設計ドキュメント集です。
## 📁 ファイル一覧
### 🌟 最新設計2025-10-02追加
- **[enhanced-architecture-v2.md](enhanced-architecture-v2.md)** ⭐必読 - ChatGPT Pro UltraThink強化版アーキテクチャ
- **[meta-config-examples.md](meta-config-examples.md)** - hako.toml設定リファレンス
- **[risks-and-mitigations.md](risks-and-mitigations.md)** - リスク管理ドキュメント
### ABI・FFI設計
- **[abi-design.md](abi-design.md)** - Python-Hakorune ABI設計
- **[handle-first-plugininvoke-plan.md](handle-first-plugininvoke-plan.md)** - Handle-First PluginInvoke設計
### ビルド・実行
- **[native-build-consolidation.md](native-build-consolidation.md)** - ネイティブビルド基盤設計
## 🎯 設計の核心
### 1. ABI設計方針
#### ハンドル管理
- **TLV tag=8**: Python object handle
- **type_id + instance_id**: 箱の識別
- **Arc<PyObject>**: Rust側での管理
#### 型変換
| Hakorune | Python | 備考 |
|---------|--------|------|
| BoolBox | bool | 真偽値 |
| IntegerBox | int | 整数 |
| StringBox | str | 文字列 |
| ArrayBox | list | 配列 |
| MapBox | dict | 辞書 |
| PyObjectBox | object | 任意のPythonオブジェクト |
### 2. Handle-First 設計
#### 原則
- 第一引数a0は常にハンドル
- `nyash.handle.of(receiver)` で変換
- TLV統一: String/Integer以外はHandletag=8
#### メリット
- 型安全性の向上
- 統一されたインターフェース
- デバッグの容易さ
### 3. GIL管理戦略
#### 基本方針
- **birth/invoke/decRef中はGIL確保**
- **AOTでも同等の処理**
- **ネスト呼び出しの安全性保証**
#### 実装パターン
```rust
pub fn invoke_python_method(handle: Handle, method: &str, args: &[Value]) -> Result<Value> {
// GIL獲得
let gil = Python::acquire_gil();
let py = gil.python();
// Pythonオブジェクト取得
let obj = get_pyobject_from_handle(handle)?;
// メソッド呼び出し
let result = obj.call_method(py, method, args, None)?;
// 結果を変換
let value = pyobject_to_value(result)?;
Ok(value)
// GILは自動解放
}
```
## 🏗️ アーキテクチャ概要
### レイヤー構造
```
┌─────────────────────────────────┐
│ Hakorune Application │
├─────────────────────────────────┤
│ Python Integration Layer │
│ - PyRuntimeBox │
│ - PyObjectBox │
├─────────────────────────────────┤
│ FFI/Plugin Interface │
│ - Handle-First design │
│ - TLV type system │
├─────────────────────────────────┤
│ CPython C API │
├─────────────────────────────────┤
│ CPython Runtime │
└─────────────────────────────────┘
```
### プラグイン構成
```
hakorune-python-plugin/
├── src/
│ ├── lib.rs # FFI entry point
│ ├── runtime.rs # PyRuntimeBox
│ ├── object.rs # PyObjectBox
│ ├── conversion.rs # 型変換
│ └── gil.rs # GIL管理
├── Cargo.toml
└── build.rs
```
## 🔧 ネイティブビルド戦略
### AOT/EXEパイプライン
```
Hakorune Source (.hkr)
↓ Parse
AST
↓ Lower
MIR
↓ JIT Compile
CLIF IR
↓ Object Generation
Object File (.o)
↓ Link (with libhakorunert.a + Python libs)
Native Executable
```
### クロスプラットフォーム対応
| Platform | Python Library | 備考 |
|----------|---------------|------|
| Linux | libpython3.X.so | 動的リンク |
| macOS | libpython3.X.dylib | 動的リンク |
| Windows | python3X.dll | 動的リンク |
## 📊 設計決定事項
### 1. Embedding vs Extending
**決定**: Embedding優先
理由:
- HakoruneからPythonを制御
- デプロイが簡単
- ユーザー体験が良い
### 2. 静的 vs 動的リンク
**決定**: 動的リンク優先、静的リンクはオプション
理由:
- Python標準の配布方法
- ライセンス問題の回避
- 柔軟性の確保
### 3. サポート対象Python
**決定**: Python 3.8以降
理由:
- 型ヒントの充実
- 十分な普及
- メンテナンス負荷
## ⚠️ リスク要因
### 1. CPython依存
- バージョン互換性
- プラットフォーム差異
- ビルド環境の複雑さ
### 2. パフォーマンス
- FFIオーバーヘッド
- GIL待機時間
- メモリコピーコスト
### 3. デバッグ困難性
- 言語境界を越えるエラー
- スタックトレースの複雑さ
- メモリリークの追跡
## 🔗 関連ドキュメント
- [Phase 20 メインREADME](../README.md)
- [Planning](../planning/)
- [Core Implementation](../core-implementation/)

View File

@ -0,0 +1,53 @@
# Phase 10.5a Python 統合 ABI 設計Draft
目的: Everything is Plugin/AOT の既存基盤上に Python を最小リスクで統合するための ABI と型・メソッド定義を固定する。
## スコープ10.5a
- v2 プラグイン ABI 準拠(`nyash_plugin_abi/init/invoke`)の Python プラグイン雛形を作成
- 2 Box を定義: `PyRuntimeBox(type_id=40)`, `PyObjectBox(type_id=41)`
- メソッド ID の割り当てと TLV 方針を文書化(実装は 10.5b 以降)
## TLV マッピング(現行運用)
- 1 = Bool (1 byte)
- 2 = I32 (4 bytes, LE)
- 3 = I64 (8 bytes, LE)
- 4 = F32 (4 bytes, LE)
- 5 = F64 (8 bytes, LE)
- 6 = String (UTF-8, n bytes)
- 7 = Bytes (opaque, n bytes)
- 8 = Handle/BoxRef (`u32 type_id || u32 instance_id`)
備考: 既存ドキュメントには古い表記の混在があるため、VM_README 準拠で統一。
## Box とメソッド設計
### PyRuntimeBox (type_id=40)
- birth(0): ランタイムの生成(後続で GIL 初期化などを担当)。戻り値: `instance_id`(非 TLV, u32 LE
- eval(1, code: String): Python コードを評価して `PyObjectBox` を返す。戻り値: `Handle(tag=8)`
- import(2, name: String): `__import__(name)` または `importlib.import_module`。戻り値: `Handle(tag=8)`
- fini(MAX): ランタイム破棄GIL 終了・クリーンアップ)
### PyObjectBox (type_id=41)
- birth(0): 予約(通常は runtime 側から生まれる)
- getattr(1, name: String): 属性取得 → `Handle(tag=8)`
- call(2, args: TLV...): 可変長引数。初期段は I64/String/Bool/Bytes/Handle のサブセットに限定。戻り値: `Handle(tag=8)`
- str(3): Python 側で `PyObject_Str` → String へ。戻り値: `String(tag=6)`
- fini(MAX): 参照カウント `Py_DECREF` に対応(後続)
## 参照管理・GIL概要
- GIL: birth/invoke/fini の入口で確保し、出口で解放(再入を許容)。
- 参照: `PyObjectBox` は生成時に `INCREF``fini``DECREF`。ランタイム終了時に孤立検知の簡易テストを導入。
## 設定ファイルnyash.toml
- `libnyash_python_plugin.so` を 2 Box 含む形で登録path/type_id/method_id を固定)
- JIT/VM 側は既存の `plugin_invoke` 経由で呼び出しAOT は 10.5d で `libnyrt.a` にシム追加)
## 次フェーズ10.5b 以降)
- 10.5b: `PyRuntimeBox`/`PyObjectBox` 実装CPython 埋め込み、最小 RO 経路)
- 10.5c: Python→Nyash 方向CPython 拡張 `nyashrt`
- 10.5d: JIT/AOT 連携(`emit_plugin_invoke` 対応・静的リンクシム)
- 10.5e: サンプル・テスト・ドキュメント
---
補足: 本ドキュメントは「設計の固定」を目的とし、実装は段階的に進める。タグ/ID は既存と衝突しない値を選定した40/41

View File

@ -0,0 +1,543 @@
# Python-Hakorune統合 強化版アーキテクチャ v2
**作成**: 2025-10-02
**ソース**: ChatGPT Pro UltraThink Mode
**ステータス**: 設計提案
---
## 📋 概要
Phase 10.5の「Active」設計を踏まえつつ、**強化版Hakorune**Effect/Capability/Contract/Policy・PHI検証・BlockVMap等の上に載せる、**安全で境界に問題を閉じ込めたPythonブリッジ**の設計書です。
---
## 🎯 ねらいPhase 10.5の「Active」意図との整合
- 最小コアで **"箱Boxに閉じ込めたPython実行環境"** を提供
- VM/LLVM/AOTラインから同じ呼び出し規約で扱える
- **当面はVMハーネスllvmlite側を使って決定実行とスモークの安定性を優先**、AOT/EXEは段階導入
---
## 🏗️ 1. Box階層木構造の基本セット
### PyRuntimeBoxルート・単一 or 少数)
**役割**:
- PythonランタイムCPython埋め込み
- `import` 解決
- GIL管理
- モジュールキャッシュ
**ライフサイクル**:
- `init`: インタプリタ起動
- `fini`: 停止
- **Capability**で"import可能モジュールFS/NET/ENV"を限定
**実装指針**:
- まずは既存 **Plugin-First**C ABI・TLVでブリッジ
- 後段で **Hakorune ABIvtable** に段階移行
- `HAKO_ABI_VTABLE` 等のgateを活用
```hakorune
box PyRuntimeBox {
// 初期化・終了
init()
fini()
// モジュール
import(name: StringBox) -> PyModuleBox
reflect(module_name: StringBox) -> PyModuleBox
// 実行
eval(code: StringBox) -> PyObjectBox
exec(code: StringBox)
}
```
---
### PyModuleBox
**役割**:
- `import "pkg.mod"` の結果をBoxとして公開
- 属性 = フィールド
- 関数 = MethodBox
**ライフサイクル**:
- `PyRuntimeBox` が所有
- `fini` で参照解除refcnt を減らす)
```hakorune
box PyModuleBox {
// 属性アクセス
get(name: StringBox) -> PyObjectBox
set(name: StringBox, value: PyObjectBox)
// 列挙
list_attributes() -> ArrayBox
}
```
---
### PyTypeBox / PyInstanceBox
**役割**:
- Pythonのクラス定義とインスタンスをBox化
- `get/setField``call_method` を統一導線に
**所有権タグ**:
- **shared**CPython RC前提
- `unique` が必要な場合は"借用トークン"で一時的に排他操作を許可
```hakorune
box PyTypeBox {
// クラス情報
get_name() -> StringBox
get_bases() -> ArrayBox
get_methods() -> ArrayBox
// インスタンス化
new_instance(args: ArrayBox) -> PyInstanceBox
}
box PyInstanceBox {
// フィールドアクセス
get_field(name: StringBox) -> PyObjectBox
set_field(name: StringBox, value: PyObjectBox)
// メソッド呼び出し
call_method(name: StringBox, args: ArrayBox) -> PyObjectBox
}
```
---
### PyFunctionBox / PyCallableBox
**役割**:
- 呼出しを `exec(args)->result`Pulse的に落として**最小ライフサイクル**で扱える
```hakorune
box PyFunctionBox {
// Pulse: 完全な一発実行
exec(args: ArrayBox) -> PyObjectBox
// メタ情報
get_name() -> StringBox
get_signature() -> StringBox
}
```
---
### PyIteratorBox / PyGeneratorBox必要に応じて
**役割**:
- `__iter__`/`__next__` をBox化
- flow実行と相性を取る
```hakorune
box PyIteratorBox {
next() -> PyObjectBox
has_next() -> BoolBox
}
box PyGeneratorBox {
send(value: PyObjectBox) -> PyObjectBox
throw(error: ErrorBox)
}
```
> **Phase 10.5の設計メモと整合**"最小の箱から着手 → 後から拡張"
---
## 🔄 2. ライフサイクル対応Hakorune流
### init/fini
**PyRuntimeBox.init()**:
```rust
fn init() {
Py_Initialize();
// import policyのロード
// キャッシュ構築
}
```
**PyRuntimeBox.fini()**:
```rust
fn fini() {
// weakref.finalize併用で安全解放循環対策
Py_Finalize();
}
```
### Pulse
**PyFunctionBox.exec** は完全Pulseinit/fini不要:
- **作用範囲はmetaのCapabilityに閉じ込め**
- 副作用は明示的にEffect宣言
### 所有権タグ
- 既定: **shared**RC準拠
- **unique** が必要な経路: `BorrowMutToken` を発行して**単発処理中のみ**排他
> これらは **管理棟のトグル**とも親和性が高いdev: 緩める / prod: 厳格)
---
## 🎭 3. Effect / Capability / Contract の外付けmeta
### Effect論理的効果名
```toml
[box.PyRuntimeBox.effects]
available = [
"py.import",
"py.fs",
"py.net",
"py.env",
"py.time",
"py.random",
"py.subprocess"
]
```
### Capability許可リスト
```toml
[box.PyRuntimeBox.capabilities]
allow = [
"py.import:math",
"py.import:json",
"py.time:monotonic"
]
deny = [
"py.subprocess",
"py.net"
]
enforce = true # devではfalse→観測のみ
```
### Contract
**Pre条件**:
```toml
[contracts.PyFunctionBox.exec]
pre = [
"args.len <= 8",
"bytes_total <= 1_000_000"
]
```
**Post条件**:
```toml
[contracts.PyFunctionBox.exec]
post = [
"result.size <= 1_000_000",
"no_exception",
"allow_none = true"
]
```
### 監査トグル
```bash
# Dev/CI
HAKO_PLUGIN_CAPS_ENFORCE=1
HAKO_CHECK_CONTRACTS=1
# Prod
HAKO_PLUGIN_CAPS_ENFORCE=1
HAKO_CHECK_CONTRACTS=0 # 警告のみ
```
---
## 🔁 4. Deterministic / Repro の扱い
### Deterministic モード
**問題**:
- `random`, `time`, `os.urandom` 等は非決定的
**解決策**:
- **Capability トークン経由**で提供するshimsを使用
**実装例**:
```python
# py.random shim
class DeterministicRandom:
def __init__(self, seed):
self._rng = random.Random(seed)
def random(self):
return self._rng.random()
# py.time shim
class LogicalClock:
def __init__(self):
self._tick = 0
def monotonic(self):
self._tick += 1
return float(self._tick)
```
**トグル**:
```bash
# Deterministic モード有効化
HAKO_DETERMINISTIC=1
HAKO_TRACE_EFFECTS=1 # 効果ログ収集
```
**メリット**:
- **flow Main.main** 実行のスナップショット再現が可能
- デバッグ容易性向上
- テストの再現性保証
---
## 🌳 5. 木構造への「落とし方」(反射 → Box化
### ビルダー(反射)
**PyRuntimeBox.reflect(module_name: String) -> PyModuleBox**:
1. `dir(module)``inspect` で**属性ツリーを走査**
2. **Box**を生成
3. **規約**:
- 公開対象は `__all__` 優先
- ない場合は `_` 先頭を除外
- `@hako_export` デコレータがあれば優先で `FunctionBox`
**実装擬似コード**:
```python
# Python側リフレクションヘルパー
def reflect_module(module_name):
mod = importlib.import_module(module_name)
# 属性リスト取得
if hasattr(mod, '__all__'):
attrs = mod.__all__
else:
attrs = [a for a in dir(mod) if not a.startswith('_')]
# Box化
boxes = {}
for attr_name in attrs:
attr = getattr(mod, attr_name)
if callable(attr):
boxes[attr_name] = create_function_box(attr)
elif inspect.isclass(attr):
boxes[attr_name] = create_type_box(attr)
else:
boxes[attr_name] = create_object_box(attr)
return boxes
```
### 使用例
```hakorune
using "python"
box Main {
flow main() {
// init: CPython起動
let py = PyRuntimeBox();
// PyModuleBox
let m = py.reflect("math");
// PyFunctionBox
let sqrt = m.get("sqrt");
// 実行
let r = sqrt.exec([2.0]);
print(r); // -> 1.4142...
// 正常停止
py.fini();
}
}
```
> 反射で"木"を作り、**Box統一APIget/set/callで走る** — Phase 10.5の「Activeは最小の箱から導入」を踏襲
---
## ⚠️ 6. 例外とエラー境界
### Python例外 → ErrorBox
```hakorune
box ErrorBox {
type: StringBox // "ZeroDivisionError"
message: StringBox // "division by zero"
traceback: StringBox // フルトレースバック
}
```
**変換例**:
```python
# Python側
try:
result = some_function()
except Exception as e:
return ErrorBox(
type=type(e).__name__,
message=str(e),
traceback=traceback.format_exc()
)
```
### Contract違反
**Strict モード**:
```bash
HAKO_EXTERN_STRICT=1 # fail-fast
```
**通常モード**:
```bash
HAKO_EXTERN_STRICT=0 # 警告 + ErrorBox返却
```
---
## 🎛️ 7. 実行ポリシーとトグル(管理棟)
### ハーネス
```bash
# 既定でPythonハーネス使用
HAKO_LLVM_USE_HARNESS=1 # デフォルトON
```
### PHIオプション
**ブリッジ互換**PHI-off:
```bash
HAKO_VERIFY_ALLOW_NO_PHI=1 # 互換用途のみ
```
**統一**PHI-on:
```bash
HAKO_VERIFY_ALLOW_NO_PHI=0 # 推奨
# Verifierを**PHI直後に常時実行**
```
**モード設定**:
- Dev: fail-fast
- Prod: 警告
### ABI
**初期**C ABI - TLV:
```bash
HAKO_ABI_VTABLE=0 # C ABI使用
```
**段階移行**Hakorune ABI - vtable:
```bash
HAKO_ABI_VTABLE=1
HAKO_ABI_STRICT=1 # フォールバック禁止
```
### Plugin観測
```bash
# CI/Dev
HAKO_TRACE_EFFECTS=1
HAKO_PLUGIN_META=1
HAKO_PLUGIN_CAPS_ENFORCE=1
```
---
## 🚀 強化版Hakoruneでの設計図アップデート
### 1. 境界検証を"必須フェーズ"に
**実装**:
- `finalize_phis()` の直後で **SSA/支配関係/到達性**を検証
- Dev: 例外
- Prod: 警告+トレース保全
**効果**:
- Pythonブリッジ有無に関わらず**毎回**回る
- IR品質を境界に閉じ込める
### 2. BlockVMap型でvmap/_current_vmapを統合
**実装**:
- 参照は必ず `BlockVMap::at(block)` 経由
- 呼び出し側から**どの視点が"真"か**を隠蔽
**効果**:
- Python連携でもブロック境界で値がぶれない
- 事故防止
### 3. InstructionContextを必須引数化
**実装**:
- すべての `lower_*` に統一コンテキストを渡す
- **ログ/例外に命令位置・BB名を強制添付**
**効果**:
- 原因追跡が一気に楽に
### 4. flow Main.main を"仕様"として固定
**実装**:
- Phase 10.5のActive方針と揃えて **flow優先**
- staticを覚える必要なし
**効果**:
- 入口の一意化
- セルフホストの再現ビルド検証にも効く
### 5. 開発→本番の昇格パスを明確化
**Dev**:
```bash
HAKO_*_ENFORCE=0
HAKO_TRACE=1
# fail-fast ON
```
**Prod**:
```bash
HAKO_*_ENFORCE=1
HAKO_TRACE=0
# fail-fast OFFErrorBox警告
```
**効果**:
- **管理棟env**にすでに集約されている設計
- 運用で迷わない
---
## 🔗 関連ドキュメント
- [マイルストーン](../planning/milestones.md) - M0〜M6の詳細計画
- [メタ設定例](meta-config-examples.md) - hako.toml設定例
- [リスクと対策](risks-and-mitigations.md) - 既知のリスクと対策
- [Phase 20 README](../README.md) - 全体概要
---
**最終更新**: 2025-10-02
**作成者**: ChatGPT Pro (UltraThink Mode)
**レビュー**: 未実施
**ステータス**: 設計提案・Phase 15完了後に実装予定

View File

@ -0,0 +1,46 @@
# Phase 10.5c — Handle-First PluginInvoke 設計(最優先計画)
目的: Python専用の型伝搬を撤廃し、プラグイン呼び出しを「Everything is Handle」で統一。Lowererは箱名や戻り型に依存しない最小知識で `PluginInvoke` を実Emitし、型解決は実行時TLV/Handleに委譲する。
## 背景と問題
- 現状のLowererに「import/getattr/call の戻りを PyObjectBox とみなす」暫定コードが混入。これは Python 特化のハードコーディングで、将来のプラグイン拡張File/Net/DB 等)にブレーキとなる。
- すでに ABI/VM は TLV tag=8Handleを標準化。戻り値を Handle として受け取り、タイプ情報type_idは実行時に判明する。
## 原則Handle-First
- すべてのプラグインメソッドの戻りは HandleTLV: tag=8またはプリミティブi64/f64/bool/string/bytes
- Lowerer は「戻り型が box かどうか」だけを気にすればよい。個々の箱名PyObjectBox 等)を前提にしない。
- 型の詳細は `type_id` によって実行時に解決される。JIT/AOT は型非依存の汎用コード生成を行う。
## 設計
1) メタデータ駆動
- `nyash_box.toml``methods.*.returns = { type = "box" | "i64" | "f64" | "string" | "void" | ... }` を単一の参照源に。
- `PluginHost.resolve_method``returns.type` を含む情報を公開Lowerer から参照)。
2) Lowerer の汎用化
- `PluginInvoke` を常に `emit_plugin_invoke(type_id, method_id, argc, has_ret)` に落とす。
- 「戻りが box のときに特定箱名を記録する」実装を撤去。必要なら「dst は Handlebox」のヒントのみ保持。
- 受け手箱名が未確定の場合に備え、by-name 経路(後述)を用意。
3) by-name シム(任意→推奨)
- `nyrt`/builder に `nyash_plugin_invoke_by_name_{i64,f64}(box_type_name?, method_name, a0, a1, a2)` を追加。
- 受け手の箱名が Lowerer 時点で特定できない場合、by-name シムを使用して実行時に `method_id` を解決。
4) 実行時の統一
- 既存の `nyash_plugin_invoke3_{i64,f64}` と同様に、TLVで引数を構築。Handle/プリミティブ変換StringBox/IntegerBoxの自動プリミティブ化を継続。
- 戻りTLVの tag を見て i64/f64 経由の値化(`NYASH_JIT_NATIVE_F64`)またはハンドル登録を行う。
## マイルストーン
- M1: Lowerer から Python特化の型伝搬を除去dst=Handle ヒントのみ)。
- M2: `PluginHost.resolve_method` 拡張で `returns.type` を取得可能に。
- M3: by-name シムの追加と Lowerer 配線(箱名未確定時)。
- M4: AOT 最小ケースimport→getattr→callを Handle-First で Green。
- M5: ドキュメントと CURRENT_TASK を刷新。
## 受け入れ条件DoD
- VM: `py.import("math"); (math.getattr("sqrt")).call(9)` が Greenautodecode=1 で 3
- AOTstrict: 上記チェーン最小例で unsupported=0。Console 出力経路は PluginInvoke または extern 経由で表示。
- Lowerer に Python 固有の型分岐が存在しないgrepで検出不可
## 運用メモ
- 将来的な最適化箱名が静的に分かる場面での特殊化は、Handle-First を壊さない範囲で「分岐の1箇所」に限定して導入する。

View File

@ -0,0 +1,531 @@
# hako.toml メタ設定例
**作成**: 2025-10-02
**ソース**: ChatGPT Pro UltraThink Mode
**用途**: Python統合のメタデータ設定リファレンス
---
## 📋 概要
Python-Hakorune統合における`hako.toml`の設定例集です。
Effect/Capability/Contract/Policyの具体的な設定方法を示します。
---
## 🎯 基本設定
### 最小構成
```toml
# hako.toml (minimal)
[box.PyRuntimeBox]
effects.allow = ["py.import:math"]
```
### 標準構成
```toml
# hako.toml (standard)
[box.PyRuntimeBox]
effects.allow = [
"py.import:math",
"py.import:json",
"py.time:monotonic"
]
capabilities.enforce = true
```
---
## 🎭 Effect設定
### 利用可能なEffect一覧
```toml
[box.PyRuntimeBox.effects]
available = [
# モジュールインポート
"py.import",
# ファイルシステム
"py.fs.read",
"py.fs.write",
# ネットワーク
"py.net.http",
"py.net.socket",
# 環境変数
"py.env.read",
"py.env.write",
# 時刻
"py.time.monotonic",
"py.time.real",
# ランダム
"py.random",
# プロセス
"py.subprocess"
]
```
### Effect許可例
```toml
[box.PyRuntimeBox.effects]
allow = [
"py.import:math",
"py.import:json",
"py.import:re",
"py.time:monotonic",
"py.fs.read:/tmp/**"
]
```
---
## 🛡️ Capability設定
### 基本Capability
```toml
[box.PyRuntimeBox.capabilities]
# 許可リスト
allow = [
"py.import:math",
"py.import:json"
]
# 拒否リスト
deny = [
"py.subprocess",
"py.net"
]
# 厳格モード
enforce = true
```
### 詳細Capabilityモジュール別
```toml
[box.PyRuntimeBox.capabilities.import]
# 標準ライブラリ
stdlib = [
"math",
"json",
"re",
"datetime",
"collections"
]
# サードパーティ(ホワイトリスト)
allow_third_party = [
"numpy",
"pandas"
]
# 拒否(ブラックリスト)
deny = [
"os",
"subprocess",
"socket"
]
```
### ファイルシステムCapability
```toml
[box.PyRuntimeBox.capabilities.fs]
# 読み取り許可
read_paths = [
"/tmp/**",
"/data/input/**",
"~/.config/app/**"
]
# 書き込み許可
write_paths = [
"/tmp/**",
"/data/output/**"
]
# 拒否
deny_paths = [
"/etc/**",
"/sys/**",
"~/.ssh/**"
]
```
### ネットワークCapability
```toml
[box.PyRuntimeBox.capabilities.net]
# HTTP許可
http_allow = [
"https://api.example.com/**",
"https://data.example.org/api/**"
]
# Socket許可ホスト:ポート)
socket_allow = [
"localhost:8080",
"127.0.0.1:5432"
]
# 拒否
deny = [
"0.0.0.0:*", # すべてのインターフェース
"*:22", # SSH
"*:3389" # RDP
]
```
---
## ✅ Contract設定
### PyFunctionBox Contract
```toml
[contracts.PyFunctionBox.exec]
# Pre条件引数チェック
pre = [
"args.len <= 8", # 引数は8個まで
"bytes_total <= 1_000_000", # 合計1MB以下
"no_file_descriptors" # ファイルディスクリプタ禁止
]
# Post条件返り値チェック
post = [
"result.size <= 1_000_000", # 返り値1MB以下
"no_exception", # 例外禁止
"allow_none = true", # None許可
"execution_time <= 5.0" # 5秒以内
]
# 違反時の挙動
on_violation = "error" # "error" | "warn" | "ignore"
```
### PyModuleBox Contract
```toml
[contracts.PyModuleBox.import]
pre = [
"module_name.len <= 100", # モジュール名100文字以内
"no_relative_import" # 相対インポート禁止
]
post = [
"module_size <= 10_000_000", # モジュールサイズ10MB以下
"no_native_code" # ネイティブコード禁止(オプション)
]
```
### PyInstanceBox Contract
```toml
[contracts.PyInstanceBox.call_method]
pre = [
"method_name.len <= 50", # メソッド名50文字以内
"args.len <= 16" # 引数16個まで
]
post = [
"result.size <= 1_000_000", # 返り値1MB以下
"no_side_effects" # 副作用禁止Pure
]
```
---
## 🎛️ Policy設定
### 開発モードDev
```toml
[policy.dev]
# Capability
capabilities.enforce = false # 観測のみ
capabilities.log = true # ログ記録
# Contract
contracts.enforce = true # 厳格チェック
contracts.on_violation = "error" # 違反時エラー
# Deterministic
deterministic = false # 非決定的許可
# Trace
trace.effects = true # 効果トレース
trace.calls = true # 呼び出しトレース
trace.errors = true # エラートレース
# Verifier
verify.phi = true # PHI検証
verify.ssa = true # SSA検証
verify.on_fail = "error" # 検証失敗時エラー
```
### 本番モードProd
```toml
[policy.prod]
# Capability
capabilities.enforce = true # 厳格適用
capabilities.log = false # ログなし
# Contract
contracts.enforce = true # 厳格チェック
contracts.on_violation = "warn" # 違反時警告
# Deterministic
deterministic = true # 決定的実行
# Trace
trace.effects = false # トレースなし
trace.calls = false
trace.errors = true # エラーのみ
# Verifier
verify.phi = true # PHI検証
verify.ssa = true # SSA検証
verify.on_fail = "warn" # 検証失敗時警告
```
### テストモードTest
```toml
[policy.test]
# Capability
capabilities.enforce = true # 厳格適用
capabilities.log = true # ログ記録
# Contract
contracts.enforce = true # 厳格チェック
contracts.on_violation = "error" # 違反時エラー
# Deterministic
deterministic = true # 決定的実行(再現性)
# Trace
trace.effects = true # 全トレース
trace.calls = true
trace.errors = true
# Verifier
verify.phi = true # 全検証
verify.ssa = true
verify.on_fail = "error" # 検証失敗時エラー
```
---
## 🔧 環境変数によるオーバーライド
### 優先順位
1. 環境変数(最優先)
2. hako.toml
3. hakorune.toml
4. デフォルト値
### 環境変数例
```bash
# Capability
export HAKO_PLUGIN_CAPS_ENFORCE=1
export HAKO_TRACE_EFFECTS=1
# Contract
export HAKO_CHECK_CONTRACTS=1
export HAKO_CONTRACT_VIOLATION=error
# Deterministic
export HAKO_DETERMINISTIC=1
# ABI
export HAKO_ABI_VTABLE=1
export HAKO_ABI_STRICT=1
# Verifier
export HAKO_VERIFY_ALLOW_NO_PHI=0
export HAKO_VERIFY_ON_FAIL=error
# LLVM
export HAKO_LLVM_USE_HARNESS=1
```
---
## 📊 実用例
### 例1: 数学計算のみ許可
```toml
# hako.toml
[box.PyRuntimeBox]
effects.allow = ["py.import:math"]
capabilities.enforce = true
[contracts.PyFunctionBox.exec]
pre = ["args.len <= 4"]
post = ["no_exception", "execution_time <= 1.0"]
```
```hakorune
using "python"
box Main {
flow main() {
let py = PyRuntimeBox();
let math = py.import("math");
let sqrt = math.get("sqrt");
let r = sqrt.exec([2.0]);
print(r); // OK
py.fini();
}
}
```
### 例2: データ処理(ファイル読み取り)
```toml
# hako.toml
[box.PyRuntimeBox]
effects.allow = [
"py.import:json",
"py.fs.read:/data/input/**"
]
[box.PyRuntimeBox.capabilities.fs]
read_paths = ["/data/input/**"]
write_paths = [] # 書き込み禁止
```
```hakorune
using "python"
box Main {
flow main() {
let py = PyRuntimeBox();
let json = py.import("json");
// ファイル読み取り(許可)
let data = py.eval("open('/data/input/test.json').read()");
let parsed = json.get("loads").exec([data]);
print(parsed);
py.fini();
}
}
```
### 例3: API呼び出しネットワーク
```toml
# hako.toml
[box.PyRuntimeBox]
effects.allow = [
"py.import:urllib",
"py.net.http"
]
[box.PyRuntimeBox.capabilities.net]
http_allow = [
"https://api.example.com/**"
]
[contracts.PyFunctionBox.exec]
pre = ["args.len <= 2"]
post = [
"result.size <= 1_000_000",
"execution_time <= 10.0"
]
```
```hakorune
using "python"
box Main {
flow main() {
let py = PyRuntimeBox();
let code = "
import urllib.request
def fetch(url):
with urllib.request.urlopen(url) as r:
return r.read()
";
py.exec(code);
let fetch = py.get("fetch");
// API呼び出し許可
let result = fetch.exec(["https://api.example.com/data"]);
print(result);
py.fini();
}
}
```
---
## 🔍 デバッグ設定
### 詳細ログ
```toml
[debug]
# すべてのトレース有効化
trace.all = true
# 個別トレース
trace.effects = true
trace.capabilities = true
trace.contracts = true
trace.python_calls = true
trace.gil = true
# ログレベル
log_level = "debug"
# ログ出力先
log_file = "/tmp/hakorune-python-debug.log"
```
### パフォーマンスプロファイル
```toml
[profile]
# タイミング記録
timing.enabled = true
timing.threshold = 0.1 # 100ms以上
# メモリ使用量
memory.track = true
memory.threshold = 10_000_000 # 10MB以上
# GC統計
gc.enabled = true
```
---
## 🔗 関連ドキュメント
- [強化版アーキテクチャv2](enhanced-architecture-v2.md) - 設計詳細
- [マイルストーン](../planning/milestones.md) - 実装計画
- [リスクと対策](risks-and-mitigations.md) - リスク管理
- [Phase 20 README](../README.md) - 全体概要
---
**最終更新**: 2025-10-02
**作成者**: ChatGPT Pro (UltraThink Mode)
**ステータス**: 設定リファレンス

View File

@ -0,0 +1,37 @@
# 10.5b ネイティブビルド基盤の固めAOT/EXE
Python統合を本格化する前に、配布可能なネイティブ実行ファイルEXEの足回りを先に完成させる。JITは実行エンジンから外し、EXE生成専用のコンパイラとして運用する。
## 🎯 目的
- VM=実行、JIT=EXEAOTの二系統を明確化フォールバックなし/Fail-Fast
- CLIF→.o→`libnyrt`リンク→EXEのパイプラインを実効化
- プラグイン解決をクロスプラットフォームに(.so/.dll/.dylib、自動lib剥がし、検索パス
- Windowsを含む実用的な配布体験を整備
## 🧩 範囲
- JIT分離・Strict運用Fail-Fast/No-fallback
- AOTパイプライン: `--compile-native``tools/build_aot.{sh,ps1}`
- プラグインローダの拡張: 拡張子変換/`lib`剥がし、`plugin_paths`+`NYASH_PLUGIN_PATHS`
- Windowsリンク: clang優先`nyrt.lib`/`libnyrt.a`両対応、bash+cc fallback
- 観測/EXE出力の統一: `Result: <val>`、終了コード=<val>
## ✅ 成果DoD
- `cargo build --release --features cranelift-jit` の後、
- Linux: `./tools/build_aot.sh examples/aot_min_string_len.nyash -o app && ./app`
- Windows: `powershell -ExecutionPolicy Bypass -File tools\build_aot.ps1 -Input examples\aot_min_string_len.nyash -Out app.exe && .\app.exe`
- プラグインは `.so` 記述でも各OSで自動解決.dll/.dylib へ変換、lib剥がし
- `tools/smoke_aot_vs_vm.sh` で VM/EXE の `Result:` 行比較が可能(差異は警告表示)
## 🔧 実装メモ
- `src/runtime/plugin_loader_v2.rs``resolve_library_path()` を追加:
- OS別拡張子、Windowsの`lib`剥がし、`plugin_paths`探索
- `src/config/nyash_toml_v2.rs``NYASH_PLUGIN_PATHS` を追加(`;`/`:`区切り)
- `AotConfigBox``set_plugin_paths()` 追加env同期
- `crates/nyrt` の EXE出力統一`Result:`/exit code
- Windows: `tools/build_aot.ps1`clang→bash fallback、Linux: `tools/build_aot.sh`
## 📌 次10.5c 以降)
- PyRuntimeBox/PyObjectBoxRO優先
- Python ABIルータを `libnyrt` に同梱type_id→invokeディスパッチ
- 配布用パッケージ整備nyash.toml/プラグイン配置ガイドの最終化)

View File

@ -0,0 +1,441 @@
# リスクと対策
**作成**: 2025-10-02
**ソース**: ChatGPT Pro UltraThink Mode
**用途**: Python統合における既知のリスクと対策
---
## 📋 概要
Python-Hakorune統合における技術的リスク、運用リスク、およびその対策をまとめます。
---
## 🔥 高リスク項目
### 1. GILデッドロック
#### リスク詳細
- **問題**: Hakorune並列実行とPython GILのズレ
- **発生条件**: Hakorune側マルチスレッド + Python呼び出しのネスト
- **影響**: プログラム全体がハング、デバッグ困難
#### 対策
**アーキテクチャレベル**:
```rust
// PyRuntimeBoxを専用スレッドで実行
pub struct PyRuntimeBox {
thread: JoinHandle<()>,
tx: Sender<PyCommand>,
rx: Receiver<PyResult>,
}
impl PyRuntimeBox {
pub fn init() -> Self {
let (tx, rx_cmd) = channel();
let (tx_result, rx) = channel();
let thread = thread::spawn(move || {
// このスレッドでGILを保持
let gil = Python::acquire_gil();
let py = gil.python();
loop {
match rx_cmd.recv() {
Ok(PyCommand::Import(name)) => {
let result = py.import(&name);
tx_result.send(PyResult::Module(result)).unwrap();
}
Ok(PyCommand::Shutdown) => break,
Err(_) => break,
}
}
});
PyRuntimeBox { thread, tx, rx }
}
}
```
**ガードレール**:
```toml
[debug.gil]
# GIL獲得・解放のログ
trace = true
# タイムアウト検出
timeout = 5.0 # 5秒
# デッドロック検出
detect_deadlock = true
```
**モニタリング**:
```bash
# GILトレース有効化
export HAKO_TRACE_GIL=1
# タイムアウト設定
export HAKO_GIL_TIMEOUT=5.0
```
#### 回避策
1. **専用スレッド**でPython実行を隔離
2. **メッセージパッシング**でHakorune-Python間通信
3. **タイムアウト**で異常検出
4. **ログ**で原因追跡
---
### 2. メモリリーク
#### リスク詳細
- **問題**: Python参照カウント管理ミス
- **発生条件**: `Py_INCREF`/`Py_DECREF`の不一致
- **影響**: メモリ使用量増大、最悪OOM
#### 対策
**Arc管理**:
```rust
// PythonオブジェクトをArcでラップ
pub struct PyObjectBox {
inner: Arc<PyObjectInner>,
}
struct PyObjectInner {
py_obj: Py<PyAny>,
}
impl Drop for PyObjectInner {
fn drop(&mut self) {
// 確実にDECREF
Python::with_gil(|py| {
self.py_obj.as_ref(py);
});
}
}
```
**weakref.finalize**:
```python
# Python側で自動クリーンアップ
import weakref
def create_hakorune_object(obj):
# finalizer登録
finalizer = weakref.finalize(obj, cleanup_callback, obj_id)
return obj
```
**リーク検出**:
```toml
[debug.memory]
# メモリトラッキング
track = true
# リーク検出
detect_leaks = true
# 定期チェック
check_interval = 10.0 # 10秒
```
**ツール**:
```bash
# Valgrind
valgrind --leak-check=full ./hakorune script.hkr
# AddressSanitizer
RUSTFLAGS="-Z sanitizer=address" cargo build
# Python memory profiler
export PYTHONTRACEMALLOC=1
```
#### 回避策
1. **Arc/Drop**で自動管理
2. **weakref.finalize**で循環参照対策
3. **定期チェック**で早期発見
4. **テスト**で継続監視
---
### 3. C拡張モジュールの扱い
#### リスク詳細
- **問題**: numpy等のC拡張は特殊な扱いが必要
- **発生条件**: ネイティブコードの直接呼び出し
- **影響**: セグフォ、未定義動作
#### 対策
**Capability制御**:
```toml
[box.PyRuntimeBox.capabilities.native]
# C拡張の許可
allow_native = true
# ホワイトリスト
allow_modules = [
"numpy",
"pandas",
"_ctypes"
]
# ブラックリスト
deny_modules = [
"ctypes", # 任意ネイティブコード実行
"cffi"
]
```
**サンドボックス**(将来):
```toml
[sandbox]
# ネイティブコードをサンドボックスで実行
enable = true
mode = "seccomp" # Linux
```
**検証**:
```rust
// ロード前に検証
fn verify_module_safety(module_name: &str) -> Result<()> {
// シグネチャ確認
// 既知の安全なモジュールか
// ブラックリスト確認
}
```
#### 回避策
1. **ホワイトリスト**で既知の安全なモジュールのみ許可
2. **サンドボックス**で隔離実行(将来)
3. **検証**でロード前チェック
---
## ⚠️ 中リスク項目
### 4. パフォーマンスオーバーヘッド
#### リスク詳細
- **問題**: FFI境界・GIL・型変換のコスト
- **影響**: 性能劣化
#### 対策
**最適化**:
```rust
// 型変換キャッシュ
struct TypeCache {
string_to_pyobject: HashMap<String, Py<PyString>>,
int_to_pyobject: HashMap<i64, Py<PyLong>>,
}
impl TypeCache {
fn get_or_create_string(&mut self, py: Python, s: &str) -> Py<PyString> {
self.string_to_pyobject
.entry(s.to_string())
.or_insert_with(|| PyString::new(py, s).into())
.clone()
}
}
```
**バッチ処理**:
```rust
// 複数呼び出しをまとめる
fn batch_call(funcs: Vec<PyFunctionBox>, args: Vec<Vec<Value>>) -> Vec<Value> {
Python::with_gil(|py| {
funcs.iter().zip(args.iter())
.map(|(f, a)| f.exec_with_gil(py, a))
.collect()
})
}
```
**ベンチマーク**:
```bash
# パフォーマンステスト
cargo bench --features python-integration
```
---
### 5. プラットフォーム固有問題
#### リスク詳細
- **問題**: Python配布形態の違いLinux/macOS/Windows
- **影響**: ビルド・実行時エラー
#### 対策
**プラットフォーム別設定**:
```toml
# Linux
[target.x86_64-unknown-linux-gnu]
python-lib = "python3.11"
python-path = "/usr/lib/python3.11"
# macOS
[target.x86_64-apple-darwin]
python-lib = "python3.11"
python-path = "/usr/local/opt/python@3.11"
# Windows
[target.x86_64-pc-windows-msvc]
python-lib = "python311"
python-path = "C:/Python311"
```
**CI/CD**:
```yaml
# .github/workflows/python-integration.yml
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['3.8', '3.9', '3.10', '3.11']
```
---
### 6. 例外伝播の複雑さ
#### リスク詳細
- **問題**: Python例外とHakoruneエラーの境界
- **影響**: エラーハンドリングの困難さ
#### 対策
**統一ErrorBox**:
```hakorune
box ErrorBox {
type: StringBox // "ZeroDivisionError"
message: StringBox // "division by zero"
traceback: StringBox // フルスタックトレース
source: StringBox // "python" | "hakorune"
}
```
**変換層**:
```rust
fn convert_py_exception(py_err: &PyErr) -> ErrorBox {
ErrorBox {
type_: py_err.get_type().name().to_string(),
message: py_err.to_string(),
traceback: format_traceback(py_err),
source: "python".to_string(),
}
}
```
---
## 📊 低リスク項目
### 7. ドキュメント不足
#### 対策
- 段階的にドキュメント整備
- コードサンプル充実
- チュートリアル作成
### 8. テストカバレッジ
#### 対策
- ユニットテスト追加
- 統合テスト充実
- E2Eテスト自動化
---
## 🛡️ リスク管理マトリックス
| リスク | 深刻度 | 発生確率 | 優先度 | 対策状況 |
|-------|-------|---------|-------|---------|
| GILデッドロック | 高 | 中 | 最優先 | 設計段階で対策 |
| メモリリーク | 高 | 中 | 最優先 | Arc/Drop自動化 |
| C拡張問題 | 高 | 低 | 高 | ホワイトリスト |
| パフォーマンス | 中 | 高 | 中 | 最適化計画 |
| プラットフォーム | 中 | 中 | 中 | CI/CD網羅 |
| 例外伝播 | 中 | 低 | 低 | ErrorBox統一 |
| ドキュメント | 低 | 高 | 低 | 段階的整備 |
| テストカバレッジ | 低 | 中 | 低 | 継続改善 |
---
## 🔍 監視・検出
### 自動検出
```toml
[monitoring]
# GIL監視
gil.timeout = 5.0
gil.alert_on_timeout = true
# メモリ監視
memory.threshold = 100_000_000 # 100MB
memory.alert_on_threshold = true
# パフォーマンス監視
performance.slow_call_threshold = 1.0 # 1秒
performance.alert_on_slow = true
```
### ログ
```bash
# すべての監視ログ
export HAKO_TRACE_GIL=1
export HAKO_TRACE_MEMORY=1
export HAKO_TRACE_PERFORMANCE=1
```
---
## 📝 インシデント対応
### 1. GILデッドロック発生時
```bash
# 1. ログ確認
cat /tmp/hakorune-debug.log | grep GIL
# 2. スタックトレース取得
kill -QUIT <pid>
# 3. デバッガー接続
gdb -p <pid>
```
### 2. メモリリーク発生時
```bash
# 1. メモリ使用量確認
ps aux | grep hakorune
# 2. Valgrind実行
valgrind --leak-check=full ./hakorune script.hkr
# 3. Python側確認
export PYTHONTRACEMALLOC=1
```
---
## 🔗 関連ドキュメント
- [強化版アーキテクチャv2](enhanced-architecture-v2.md) - 設計詳細
- [マイルストーン](../planning/milestones.md) - 実装計画
- [メタ設定例](meta-config-examples.md) - 設定例
- [Phase 20 README](../README.md) - 全体概要
---
**最終更新**: 2025-10-02
**作成者**: ChatGPT Pro (UltraThink Mode)
**ステータス**: リスク管理ドキュメント