デバイスパッケージ実装契約(再現用仕様)

この文書は、今後 AI アシスタントや開発者が 同じ設計原則でデバイスパッケージを実装するための契約 です。現時点の実装範囲と未完了事項を混同しないでください。

必ず維持する原則

  1. 単一の共通 DeviceProxy はファクトリ。通信抽象化層ではない。デバイスクラス名から登録済み callable を検索し、引数をそのまま渡して結果を返す。

  2. デバイスクラス名は一意。同名登録は拒否。(device_class, transport) の複合キーは採用しない。

  3. 各デバイスパッケージが専用クライアントを提供。HTTP なら AsyncCobottaClient / SyncCobottaClient のような実在クラスを使用。架空の CobottaClient を導入しない。

  4. ファクトリに同期・非同期の選択を任せる。HTTP/gRPC の既存ペアには make_async_sync_factory を使える。Tango に同じ同期・非同期選択を強制しない。

  5. デバイス固有引数を変更しない。config、api_spec、接続先などはデバイスパッケージの仕様。共通ファクトリが解釈・補完しない。

  6. 自動探索しない。entry_points、インストール済みモジュール列挙、DB、ネットワーク探索を追加しない。利用者は必要なパッケージを把握し、明示的に import / 初期化する。

  7. 既存利用形態を壊さない。単独デバイスでは専用クライアントの直接生成、パッケージ固有 DeviceProxy、共通 DeviceProxy のいずれも許容。

  8. フレームワークを相互依存させない。共通パッケージは HTTP/gRPC/Tango を import しない。通信と動的ディスパッチは各フレームワークが担当。

  9. .pyi とドキュメントを無視しない。既存の専用クライアント .pyi を参照する共通スタブ生成器はあるが、実デバイスへの適用と型チェッカー検証は未実施。

実装手順

  1. 既存のデバイスクラス・専用クライアントクラス・コンストラクタを実際のソースから確認する。

  2. デバイスパッケージ内に、専用クライアントを生成する callable を定義する。既存の同期・非同期ペアなら make_async_sync_factory を利用してよい。

  3. パッケージの明示的な import または初期化処理で register_device_proxy("一意なクラス名", creator) を呼ぶ。

  4. 同一プロセスから異なる二つ以上のデバイスクラスを DeviceProxy で生成するテストを追加する。

  5. 単独利用(直接生成・パッケージ固有プロキシ)が壊れていないことを確認する。

  6. 通信実機テストと .pyi 生成テストを別途実施し、未実施ならその旨を記録する。

  7. README と Pages の日本語・英語版を同時更新する。

禁止する典型的な設計逸脱

  • register_backend のような通信方式レジストリを増やすこと。

  • 同じデバイスクラス名を HTTP/gRPC/Tango ごとに重複登録すること。

  • 共通 DeviceProxy に async_mode や config の意味を固定すること。

  • pip install しただけでデバイスクラス名を自動解決できると説明すること。

  • 既存の AsyncCobottaClient / SyncCobottaClient を存在しない単一クラスに置き換えること。

実装済み API

register_device_proxy(device_class, creator)、DeviceProxy(device_class, *args, **kwargs)、create_device_proxy(device_class)、get_device_proxy_entry(device_class)、list_device_proxies()、unregister_device_proxy(device_class)、make_async_sync_factory(...)。

この仕様は 共通ファクトリの現行試作に対する契約 です。既存デバイスパッケージ側の移行と実デバイス型スタブの検証は未実施です。