第 6 章 エラーと可観測性

エラーモデルと可観測性は Fayger の三層を横断する二本の共通配線です。これらにより、外部呼び出し側は同じ意味論で失敗を理解し、特定し、実行を監視できます。

6.1 統一エラーモデル

struct FaygerError {
  code: ErrorCode
  source_layer: Layer       // loader | runtime | adapter | host
  message: String
  context: Map<String, Value>
  cause: Option<Box<FaygerError>>
}

フィールド意味:

  • code:安定で文書化可能な識別子。呼び出し側の分岐判断に使用。バージョンを跨いで意味を変えない。
  • source_layer:エラーを最初に生んだ層を示す。対応する診断資料へのルーティングに有用。
  • message:人向けの説明。短く、code 情報を反復しない。
  • context:ツール向けの構造化キーバリュー。エラーを引き起こした主要フィールド(offset、missing_fields、current_state、expected_range など)を最低限含む。
  • cause:層を跨ぐエラー因果連鎖。エラーを包む際に下層エラーを cause に入れ、情報を呑み込まない。

6.2 エラー発生と伝播の規則

  1. 発生地点で構築:各層は自分の境界内で FaygerError を構築し source_layer を付ける。
  2. 段階的に包む:上層が意味を補強する場合、下層エラーを cause に保持し、source_layer を書き換えない。
  3. 文脈を失わないcontext はエラーを起こした主要フィールドを最低限含む。
  4. 失敗保持Failed に入った BuF_Instance は、最後の Universal_Instruction と対応エラーを failure_info に固定し、明示的に破棄されるまで保持する。

6.3 エラー連鎖の例

三層を跨ぐ伝播の典型:

[top]  RT_INSTANCE_FAILED      (source_layer = runtime)
         └── cause:
[mid]    ADP_HOST_CALL_FAILED  (source_layer = adapter)
           └── cause:
[low]      <ホスト原始エラー>   (source_layer = host)

cause を辿った層列は [runtime, adapter, host] で、実際の発生順序「内から外へ」に対応します。プロパティテストで継続検証します。

6.4 主要エラーコード一覧

発生層エラーコード発生条件
LoaderLDR_PARSE_FAILBuF バイト列が不正
LoaderLDR_DIGEST_MISMATCHSection ダイジェスト不一致(Eager)
LoaderLDR_LAZY_DIGEST_MISMATCHSection ダイジェスト不一致(Lazy 初回アクセス)
LoaderLDR_SIGNATURE_FAIL強制モード下の署名欠落、または署名無効
LoaderLDR_SCHEMA_UNSUPPORTEDschema バージョンが対応範囲外
LoaderLDR_RUNTIME_VERSION_TOO_HIGH必要 Runtime_Interface が現状より高い
LoaderLDR_MISSING_REQUIRED_FIELD直列化時に Manifest 必須欄欠落
LoaderLDR_PROFILE_REQUIRED_SECTION_MISSING現プロファイル下で Required Section がロード不可
LoaderLDR_LAZY_SOURCE_UNAVAILABLELazy 後続アクセスで BuF_Source 利用不可
LoaderLDR_SOURCE_READ_FAILEDBuF_Source 読み出しエラー(Eager または Lazy)
RuntimeRT_ILLEGAL_TRANSITION不正なライフサイクル遷移
RuntimeRT_IMPL_NOT_FOUNDルーティングで一致実装が見つからない
RuntimeRT_IMPL_MISSING_METHODS登録された実装が必須メソッドを欠く
RuntimeRT_QUOTA_EXCEEDEDリソース利用がクォータ超過
RuntimeRT_INSTANCE_FAILEDインスタンスが Failed に入った
AdapterADP_NO_MATCHING_PLATFORM現ホストに適合するアダプタなし
AdapterADP_UNSUPPORTED_INSTRUCTION現アダプタが当該命令を未サポート
AdapterADP_CAPABILITY_DENIED削減後のケーパビリティ不足
AdapterADP_HOST_CALL_FAILEDシステム呼び出し翻訳後ホスト側失敗

ロード層エラーは context.phase フィールドで eager または lazy を示し、呼び出し側がフェーズに応じてルーティングできます:起動期失敗は別ソース、別プロファイルへの再試行を引き起こせます。実行期 Lazy 失敗は通常その Section のアクセスのみに影響し、呼び出し側が縮退するか判断します。

6.5 可観測性イベントバス

interface EventBus {
  publish(event: FaygerEvent)
  subscribe(filter: EventFilter, handler: EventHandler) -> SubscriptionId
  set_debug_enabled(enabled: bool)
}

イベント分類:

  • Lifecycle Event:BuF_Instance の状態遷移。fromtotimestampinstance_id を保持。
  • Quota Event:リソースサンプリング、超過、停止。
  • Loader Event:ロード段の進入 / 完了 / 失敗。段名を保持。
  • Adapter Event:命令ディスパッチ、ケーパビリティ削減結果、未対応命令の記録。
  • Debug Eventset_debug_enabled(true) のときだけ出力。深い分析用。

Lifecycle イベント列の整合性

任意のインスタンスの合法遷移列 [(s₀, s₁), (s₁, s₂), …] に対し、イベントバスが発する列は次を満たす必要があります:

  • 同じ長さ。
  • eᵢ.from == sᵢ₋₁eᵢ.to == sᵢ
  • eᵢ.timestamp は単調非減少。

6.6 ホストログ / トレースチャネルとの統合

ホストがログ / トレースチャネル(systemd-journal、OS Logger、ブラウザ console、In-App SDK チャネルなど)を提供する場合、アダプタ層が Fayger 内部イベントをそのチャネルへマッピング:

  • マッピング規則は Platform_Adapter が自描述。ランタイム層はチャネル差を意識しない。
  • イベントレベル(debug / info / warn / error)はホストチャネルの対応レベルに対応。
  • Lifecycle Event と Loader Event は info、Quota / Adapter エラーは warn / error。

ホストにログチャネルがなければ、イベントは EventBus に留まり購読者が消費します。

6.7 デバッグイベントスイッチ

デバッグレベルイベント出力は既定で無効。有効化:

event_bus.set_debug_enabled(true)

デバッグイベントには次が含まれます:

  • 各 Universal_Instruction のディスパッチ詳細。
  • 各ケーパビリティ削減の入力と出力。
  • リソース監視の各サンプル値。

量が多いため、購読者は能動的に絞り込み、レート制限、ファイル落としを行うべきです。

6.8 状態問い合わせインターフェイス

Fayger は運用と診断のため次の問い合わせを公開します:

問い合わせ戻り値
state(instance_id)現在の Lifecycle_State
failure_info(instance_id)失敗を引き起こした最後の Universal_Instruction とエラーオブジェクト
list_implementations()登録済 Runtime_Implementation 記述子のリスト
current_adapter()現在選択された Platform_Adapter 記述子
granted_capabilities(instance_id)削減後にインスタンスが保有する実ケーパビリティ集合

これらは読み取り専用、冪等、任意の状態で呼び出し可能。

6.9 既定セキュリティ姿勢

  • 強制署名モードは既定 OFF(開発便宜のため)、リリース版では設定層で ON をお勧めします。
  • デバッグイベントは既定 OFF。明示的に有効化してください。
  • 宣言されないケーパビリティは BuF に対して 既定拒否
  • 認識されない Universal_Instruction カテゴリは 既定拒否。「黙って通す」ことは認めません。