本文へスキップ
Ankole

Control Plane Plugins

AI Agent 向け: このページの Markdown 版は https://ankole.agentbull.com/ja-JP/docs/control-plane-plugins/index.md にあります。ドキュメント索引は https://ankole.agentbull.com/ja-JP/llms.txt にあります。

Control Plane Plugins は、Ankole デプロイメントインスタンスが自身のコントロールプレーンを拡張する方法です — シグナル adapter、Identity Provider、AppConfigure キー、監督付きプロセスを、ワンオフのコード経路としてコントロールプレーンに増やすことなく追加します。このページはそのモデルを Ankole.Plugins の実コードにマッピングします。

決定的な性質を先に述べます: これらはリリースにコンパイルされるファーストパーティの Elixir モジュールであり、インストール可能な拡張のマーケットプレイスではありません。plugin は起動時に発見・検証され、1 つのグローバルな有効化リストでオプトインされ、次のプロセス起動でのみアクティブになります。ホットロードも、サードパーティ発見も、分離機構もありません。意図的です。

意味の異なる 2 つの段階

plugin のライフサイクルには 2 つの段階があり、この区別は決定的です:

  • 発見済み(Discovered) — 起動時に見つかり検証されたすべての plugin モジュール。有効かどうかに関わらず、オペレーターが見られる完全なカタログです。
  • アクティブ(Active) — グローバルな有効化リストにある発見済み plugin。アクティブな plugin だけが AppConfigure キーを登録し、監督付きの子プロセスを開始します。

発見済みだがアクティブではない plugin は見えるけれど不活性です。その宣言は消費するサブシステムに届かず、子も実行されません。これによりオペレーターは 1 つにコミットする前にカタログ全体を調査できます。

plugin コントラクト

plugin は Ankole.Plugins.Plugin に対する小さなコールバック集合を実装する Elixir モジュールです。必須は 1 つだけ:

  • plugin_id/0 — plugin のアイデンティティ。~r/\A[a-z][a-z0-9_-]*\z/ に一致する小文字のスラッグ。

残りは任意で、モジュールがエクスポートしない場合はデフォルトで空または nil になります:

  • display_name/0、description/0 — オペレーターサーフェスのためのローカライズされたテキスト。
  • app_config_definitions/0、app_config_patterns/0 — plugin が寄与する AppConfigure キー。
  • adapter_declarations/0 — plugin をサブシステム契約に差し込むための汎用エンベロープ。
  • children/0 — plugin が開始したい監督付き子仕様。

Spec.from_module/1 は起動時にこれらのコールバックを読み取り、Spec に正規化します。検証は plugin 所有の形状(アイデンティティ、ローカライズされたテキスト、AppConfigure 宣言、子、adapter 宣言エンベロープ)について厳密で、エラーは問題のモジュールでラップされるため、起動失敗は責任のある plugin を指します。

サブシステム契約

plugin は名前付き契約を通じてサブシステムに差し込みます。契約 id はドットを含むことができ、サブシステムが名前空間化できます。実際に使われている契約:

  • signals_gateway.adapter — SignalsGateway が adapter レジストリに解決する Signal adapter を宣言します。これにより新しいチャット・イベント provider がバインディング対象として利用可能になります。
  • signals_gateway.webhook_handler — /webhooks/v1/:handler_id/:instance_id/:kind フロントドアのハンドラーを宣言します。ハンドラーは provider 認証を所有し、正規化された事実を ingress に呼び出します。
  • principals.identity_provider — オペレーターが管理者サインイン用に設定できる Identity Provider を宣言します。

契約固有のコールバック意味論は、契約を消費するサブシステムに残ります。plugin レジストリは汎用の adapter 宣言エンベロープだけを保持し、サブシステム(例: SignalsGateway.Adapters)が自分の契約 id の宣言を読み取り、解釈します。この分離により、レジストリは無知なカタログ、サブシステムは賢い消費者になります。

有効化境界: 次回のプロセス起動

plugin はインスタンス全体でフェイルクローズされるため、オペレーターは 1 つの永続的なリスト plugins.enabled_ids(PostgreSQL に保存される AppConfigure キー)で明示的にオプトインします。レジストリはコントロールプレーン起動時に init/1 でそのリストを一度だけ読み取ります。

有効化リストの変更は直ちに効果がありません。次の Ankole プロセス起動で効果があります。これは意図的です。plugin のアクティブ化・非アクティブ化は監督付きの子プロセスと設定キーを追加・削除でき、これはホットスワップではなく起動時(boot-time)の関心事です。したがって Console の PUT /control-plane-plugins ルートは「次のプロセス起動のための 1 つの Control Plane Plugin を設定する」とラベル付けされています — 意図を書き込み、再起動がそれを適用します。

レジストリ自体は、プロセスの存続期間中状態が不変の GenServer です。init/1 中にモジュール検証、一意性不変条件、設定登録が失敗すると、:stop を返します。これにより、部分的に登録された plugin セットでシステムが動く前にアプリケーション起動が停止します。悪い plugin は静かにではなく、はっきりと起動を失敗させます。

オペレーターサーフェス

モデルをカバーする 2 つのコンソールスコープのルート:

メソッド パス 目的
GET /control-plane-plugins アクティブな plugin と次回起動時の plugin 状態を一覧表示
PUT /control-plane-plugins 次のプロセス起動のために 1 つの plugin を設定

どちらも Console ポリシー(control_plane_plugins の read と update アクション)を通るため、Console の他の部分と同じ管理者権限の下にあります。一覧応答は現在アクティブなものと次回起動に向けてステージされたものの両方を示し、オペレーターは両者を区別できます。

ファーストパーティ拡張モデルとの関係

プロジェクトの設計ルールは、拡張モデルを信頼されたファーストパーティとして扱うことです。Control Plane Plugins はまさにそのサーフェスです。plugin は拡張するコードと並んでリリースにコンパイルされ、コントロールプレーンと同じ信頼ドメインで実行されます。plugin とコントロールプレーンの間にサンドボックスはありません。plugin は契約を通じて自分を宣言したコントロールプレーンコードだからです。

モデルが止まるところで止まる理由はここにあります。サードパーティのマーケットプレイスも、ホットローディングも、plugin ごとの分離もありません。それらは異なるスレットモデルを持つ別の製品になるからです。その代わりにこのモデルが提供するのは、コントロールプレーンがすでに消費する方法を知っている能力をファーストパーティコードが寄与するための規律ある方法です。起動時に検証され、明示的なオペレーター選択でアクティブ化されます。

Control Plane Plugins がそうでないもの

ランタイムの plugin ストアでも、オペレーターがレビューしていないコードを配布する方法でもありません。Agent Computer Worker のツールや Skill が置かれる場所でもありません。それらは Agent Library の能力と worker 側のツールです。そしてホット設定可能でもありません。次回起動ルールが契約であり、plugin が変えるもの(子、設定キー)が起動時の関心事だから存在します。境界は明確です: 契約を通じて宣言され、起動時に検証され、次回起動でアクティブ化されるファーストパーティコード。

次のステップ

  • plugin が宣言できるシグナル adapter については、SignalsGateway ページを読んでください。
  • plugin が寄与する AppConfigure キーについては、Console ページを読んでください。
  • この拡張サーフェスが置かれる信頼モデルについては、Principal and AuthZ を読んでください。