第 6 章:制御権ハンドオーバープロトコル
本章は Handover_Policy(制御権ハンドオーバーポリシー)のプロトコルフローを定義する。3 種類のポリシーのセマンティクス、ハンドオーバーの原子性保証、タイムアウトロールバックおよび通知メカニズムを含む。本章はブループリント §2.4 の設計意図に対応する。
6.1 適用シナリオ
制御権ハンドオーバーは、複数の制御者が同一の Terminal_Resource を順次使用する必要があるシナリオで発生する。本仕様は 2 種類のコアハンドオーバーを定義する:
- Fay-to-Fay:ある Fay がその保有する Session 制御権を別の Fay に移転する
- Fay-to-Human:Fay が制御権を人間ユーザーに返却する、または人間ユーザーが制御権を Fay に委任する
本仕様は Fay-to-Fay を主要な記述対象とする。Fay-to-Human ハンドオーバーは同じフローを再利用し、「人間ユーザー」を特殊なインタフェースを通じて端末 OS と直接相互作用するエンティティとしてモデル化する。
6.2 ハンドオーバー発動
6.2.1 発動条件
ハンドオーバーは以下のシナリオのいずれかで発動される:
- 新 Fay によるリソース主動要求:Fay-B が AuthRequest を通じて Fay-A が占有しているリソースへのアクセスを要求
- 現 Fay の主動譲渡:Fay-A が
SessionTransferRequestを通じて、指定された Fay-B に制御権を渡すことを主動要求 - 管理発動:人間ユーザーまたは管理インタフェースが制御権移転を要求
6.2.2 ハンドオーバー要求メッセージ
SessionTransferRequest (body of ProtocolMessage) {
required source_session_id : Session_ID // 現在制御権を保有する Session
required target_fay_id : Fay_ID // 引き継ぎ対象
required target_credential : CredentialContent // 対象の認可クレデンシャル
required handover_reason : string
optional handover_metadata : map<string, string>
}
端末はハンドオーバー要求受領後、ハンドオーバー評価フローを起動する。
6.3 ハンドオーバー評価
端末は以下のステップでハンドオーバーを許可するか評価する:
6.3.1 ステップ 1:ソース Session 検証
source_session_idに対応する Session が存在し、active状態であることを検証- 発信者がハンドオーバーを要求する権限を有することを検証(当該 Session の iFay_Runtime または管理権限を有するエンティティ等)
失敗 → E_HANDOVER_INVALID_SOURCE を返却
6.3.2 ステップ 2:対象認可検証
target_credentialが合法であることを検証(第 3/4 章規則に従い完全検証)target_fay_idが当該リソースに対し元 Session のaccess_modeで認可されていることを検証
失敗 → E_HANDOVER_INVALID_TARGET を返却
6.3.3 ステップ 3:ポリシー評価
端末は §6.4 に従い Handover_Policy を適用しハンドオーバーを許可するか決定する。
失敗 → E_HANDOVER_REJECTED_BY_POLICY を返却
6.3.4 ステップ 4:原子性事前占有
端末はポリシー評価通過後、直ちに元 Session を handover_pending に切り替え、事前占有状態に入る:
- 当該リソースはハンドオーバー完了前に他の制御権要求を受け入れない
- 元 Session は依然ハートビートを維持できる(active と等価のハートビート要件を保持)が、新規リソース操作を発信できない
6.4 ハンドオーバーポリシー種別
Handover_Policy は Resource_ID 粒度で構成され、各リソースは MAY 異なるポリシーを採用する。本仕様は 3 種類のポリシー種別を定義し、すべての端末は MUST 少なくとも §6.4.1 優先順位ルールスクリプトを実装する。
6.4.1 優先順位ルールスクリプト(Priority Rule Script)
端末は事前定義されたルールスクリプトに従い、ソース Session と対象 Fay の優先順位スコアを計算し、スコアが高い方が制御権を獲得する。
構成構造:
PriorityPolicyConfig {
required policy_type : "priority_script"
required script_id : string // 端末事前構成のスクリプト識別子
optional parameters : map<string, string>
}
評価フロー:
- 端末は
script_idに対応するルールスクリプトをロード - 入力:ソース Session 情報、対象 Fay 識別子、対象クレデンシャル grants、現在時刻、Resource_ID メタデータ
- 出力:ソース優先順位スコア
S_source、対象優先順位スコアS_target - 決定:
S_target > S_source→ ハンドオーバー許可;そうでなければ拒否
ルールスクリプトの具体的言語(CEL、Lua サブセット、JSON Logic 等)は実装が選択するが、MUST:
- 確定的(同じ入力で同じ出力を生成する)
- ネットワークまたはファイルシステムにアクセスできない
- 実行時間は 100 ms 内に制限される
6.4.2 AI モデルリアルタイム判定(AI Model Real-time Decision)
端末は事前統合された AI モデルを呼び出し、現在のコンテキストに対しリアルタイム判定を行う。
構成構造:
AIPolicyConfig {
required policy_type : "ai_model"
required model_endpoint : string // 端末がアクセス可能なモデル推論エンドポイント
optional context_fields : array<string>
required decision_timeout_ms : uint32 (default 500)
}
評価フロー:
- 端末は決定要求を構築、source/target 情報と
context_fieldsで指定されたコンテキストを含む - AI モデル推論エンドポイントを呼び出し
- モデルは決定を返却:
allow/reject/require_human require_humanの場合 §6.4.3 人間ユーザー決定にデグレード
端末は MUST:
- 強制タイムアウトを設定(デフォルト 500 ms)、タイムアウトは
rejectで処理 - 高頻度変動回避のため最近の決定結果をキャッシュ(キャッシュ有効期間 ≤ 5 秒)
- AI モデル利用不可時は優先順位ルールスクリプトにデグレード
6.4.3 人間ユーザー決定(Human User Decision)
端末はユーザーインタフェースを通じて人間ユーザーに決定を要求する。
構成構造:
HumanPolicyConfig {
required policy_type : "human_decision"
required ui_channel : enum["system_dialog", "companion_app", "external_panel"]
required decision_timeout_seconds : uint32 (default 30)
required default_action : enum["allow", "reject"] // タイムアウト時のデフォルト動作
}
評価フロー:
- 端末は
ui_channelを通じて人間ユーザーにハンドオーバー要求の詳細を呈示 - ユーザー入力を待機:許可 / 拒否
- タイムアウト →
default_actionに従い処理
人間決定モードは MUST:
- UI に明示的に表示:ソース Fay 識別子、対象 Fay 識別子、リソース識別子、アクセスモード、ハンドオーバー理由
- UI に機微なクレデンシャル詳細(署名、鍵 ID 等)を表示しない
- デフォルト動作は
reject(保守的セキュリティ)に設定することを推奨
6.5 原子性保証
ハンドオーバーは MUST 原子性を満たす:任意の時点で 1 つの Resource_ID は最多 1 つのアクティブ制御者を持つ。
6.5.1 原子シーケンス
端末は MUST 以下の順序でハンドオーバーを実行し、各ステップはクリティカルセクション内で完了する:
[T0] handover_pending 進入:ソース Session 状態切り替え、リソース事前占有状態へ
[T1] ソース Session 終了:source_session_id 状態 active → terminating
OS アクセス制御取り消しを発動
[T2] リソース回収完了:source 状態 terminating → terminated
この時点でリソースは「アクティブ Session なし」状態
[T3] 対象 Session 作成:§5.2 フローに従い対象 Fay のために新 Session を作成
状態は creating に進入
[T4] OS アクセス制御下発:対象 Fay にリソースアクセスを有効化
[T5] 対象 Session が active に切り替え:ハンドオーバー完了
外部観察者が [T2] と [T3] の間で観察するリソース状態は「アクティブ Session なし」であり、2 つの Session が同時にアクティブな状態を観察することはない。
6.5.2 中間ステップ失敗時のロールバック
[T0]–[T2] 中の任意のステップが失敗した場合:
- ソース Session は MUST
activeにロールバックする - リソース回収事前占有を取り消し
E_HANDOVER_FAILED_AT_RELEASEを返却
[T3]–[T4] が失敗(ソースは終了済みだが対象を作成不可)した場合:
- 端末は MUST 直ちにリソースをクリーンアップ(リソースは「アクティブ Session なし」状態に進入)
- 元 iFay_Runtime(ソース Session は終了済み)と対象 iFay_Runtime(引き継ぎ失敗)に通知
E_HANDOVER_FAILED_AT_ACQUIREを返却- リソース状態:アイドル状態を維持し、後続要求が競合する。MUST NOT ソース Session を自動復元
6.5.3 並行ハンドオーバー要求の直列化
同一リソースに対する複数の並行ハンドオーバー要求は MUST 直列化される:
- リソースが
handover_pending期間中、新規ハンドオーバー要求はキューに入れられるか拒否される - 実装は MAY 拒否(
E_HANDOVER_IN_PROGRESS)またはキュー入り(最大キュー長 8)を選択できる - キュー入りした要求は FIFO で処理され、各要求は前のハンドオーバーが完了(成功または失敗)した後にのみ評価に進む
6.6 タイムアウト処理
各ハンドオーバーは MUST 強制タイムアウトを設定する。タイムアウト閾値はポリシー種別で決定される:
| ポリシー種別 | デフォルトタイムアウト | 範囲 |
|---|---|---|
| 優先順位ルールスクリプト | 1 秒 | 0.5–2 秒 |
| AI モデルリアルタイム判定 | 1 秒 | 0.5–3 秒 |
| 人間ユーザー決定 | 30 秒 | 5–120 秒 |
6.6.1 タイムアウトロールバック原則
ハンドオーバーがタイムアウト内に完了しない場合([T5] に到達していない)、端末は MUST:
- 現在進行中のハンドオーバーステップを中止
- [T0]–[T2] にある場合(ソースが完全に終了していない):元 Session の active 状態へロールバック
- [T3]–[T4] にある場合(ソースは終了済み):§6.5.2 に従い処理(ソースを復元せず、リソースをアイドル状態にする)
- 関連方に
HandoverFailedNotificationを送信
6.6.2 タイムアウト通知
HandoverFailedNotification (body of ProtocolMessage) {
required handover_id : uuid
required source_session_id : Session_ID
required target_fay_id : Fay_ID
required reason : enum["timeout", "policy_rejected", "release_failed", "acquire_failed"]
optional details : map<string, string>
}
6.7 リトライポリシー
ハンドオーバー失敗後のリトライポリシーは発信者が決定する。本仕様はリトライメカニズムを強制しないが、リトライの境界を定義する:
- 同一ハンドオーバー要求のリトライ間隔は SHOULD ≥ 1 秒
- 同一 (source_session, target_fay) ペアのリトライ回数は SHOULD ≤ 3 回
- リトライは MUST 新しい handover_id を使用する
端末は MAY 過度に頻繁なリトライ要求を拒否し E_HANDOVER_RETRY_LIMIT を返却できる。
6.8 Fay-to-Human ハンドオーバー
制御権を人間ユーザーに返却するハンドオーバーは上述のフローに従うが、対象は人間ユーザーである:
target_fay_idフィールドは特殊値"human:" + terminal_idを使用する(現在の端末の人間ユーザーを意味する)- 対象認可検証はスキップされる(人間ユーザーは自身の端末のリソースに対しデフォルトで完全な権限を有する)
- ポリシー評価は通常 §6.4.3 人間ユーザー決定を使用する(引き継ぎ意思の確認)
- 対象 Session 作成時、Session はいかなる Fay にもバインドされず、OS ユーザープロセスが直接保有する
人間ユーザーが主動的に引き継ぐ逆フローも対称:元 Fay Session を人間が保有する OS プロセスに置き換える。
6.9 ハンドオーバーの可観測性
端末は MUST 以下にハンドオーバーイベントの可観測性を提供する:
| 受信者 | 受信するイベント |
|---|---|
| ソース iFay_Runtime | SessionStateChanged(active → handover_pending → terminating → terminated) |
| 対象 iFay_Runtime | AuthResult(新 Session 作成の成功応答)または HandoverFailedNotification |
| 端末監査ログ | 完全なハンドオーバー記録(handover_id、source、target、policy 決定、最終結果を含む) |
6.10 ハンドオーバーメッセージシーケンス
成功ハンドオーバーの完全メッセージシーケンス:
[Source Runtime] [Target Runtime] [Terminal]
│ │ │
│── SessionTransferRequest ─────────────→│
│ │ │── ポリシー評価
│ │ │── source: active → handover_pending
│←─ SessionStateChanged(handover_pending)│
│ │ │── source 終了
│←─ SessionStateChanged(terminating)─────│
│←─ SessionStateChanged(terminated)──────│
│ │ │── target 作成
│ │←─ AuthResult ────│
│ │ │── target: creating → active
│ │←─ SessionStateChanged(active)
失敗ロールバックのメッセージシーケンス:
[Source Runtime] [Target Runtime] [Terminal]
│ │ │
│── SessionTransferRequest ─────────────→│
│ │ │── ポリシー評価
│ │ │── source: active → handover_pending
│←─ SessionStateChanged(handover_pending)│
│ │ │── タイムアウトまたは失敗
│ │ │── source: handover_pending → active
│←─ SessionStateChanged(active)──────────│
│←─ HandoverFailedNotification ──────────│
│ │←─ HandoverFailedNotification
