npx @adcp/sdk@latest storyboard run を実行できる」の間のチェックリストです。
ランナーが必要とする 3 つのサーフェス
ランナーは、バイヤーが呼ぶのと同じ公開ツール、加えてフィクスチャセットアップ用の 1 つのサンドボックス専用ツールを通じてエージェントを駆動します。3 つのサーフェスが整っていなければなりません:
あなたはこれら 3 つのサーフェスを出荷します。ランナーはストーリーボード選択、フィクスチャ順序、レスポンス比較を所有します。
Step 1 — ケイパビリティを正直に宣言
get_adcp_capabilities は、ランナーがどのストーリーボードがあなたに適用されるかを選ぶ方法です。それは 適合性 コントラクトでもあります: あなたは宣言したものに一致するすべてのストーリーボードを通過することを約束しています。
下の例はフルサービスの保証セラー(プロポーザルライフサイクル有効)用です。直接購入の保証セラーは media_buy.supports_proposals: false を設定(または省略)します。放送 TV セラーは sales-broadcast-tv を主張します。クリエイティブのみのエージェントは creative-ad-server または creative-generative 専門分野で creative プロトコルを主張します。シグナルプロバイダーは signals を主張します。パターンは同じ: 実際に実装するもののみを宣言。
supported_protocols—/compliance/{version}/protocols/から一致するプロトコルストーリーボードを引き込む。specialisms— オプトイン専門分野ストーリーボードを引き込む(完全な列挙については Compliance Catalog を参照)。account.sandbox: true— サンドボックスセマンティクス(実際の支出なし、本番副作用なし)を尊重することをシグナル。account.require_operator_auth— サンドボックスブートストラップパス(ステップ 2)を決定。
Step 2 — サンドボックスブートストラップパスを選ぶ
ランナーは何かをする前にサンドボックスアカウントを取得しなければなりません。require_operator_auth フラグがパスを選びます:
バイヤー宣言アカウント(require_operator_auth: false)。 エージェントは任意の認証されたバイヤーからの sync_accounts を受け入れます。ランナーは sandbox: true で sync_accounts を呼びオンデマンドでテストアカウントを鋳造します。ほとんどの新しいセールスエージェントはここから始めます。
アカウント ID 名前空間(require_operator_auth: true)。 アカウントはあなた側の人間または上流プラットフォームによって事前プロビジョニングされなければなりません。ランナーはサンドボックスフィルターで list_accounts を呼び既存のテストアカウントを発見します。認証情報が正確に 1 つのサンドボックスアカウントにバインドされている場合、そのシングルトンを返します。オペレーターに 1 つを要求する方法を伝える短いノートを公開します — 連絡先、期待されるターンアラウンド、受け取る認証情報を含めます。
完全な詳細と例: サンドボックスモード。
Step 3 — コンプライアンステストコントローラーを実装
コンプライアンステストコントローラーなしでは、ランナーはバイヤー開始のフロー(観察モード)のみをテストします — スキーマ適合性、auth 拒否、ハッピーパスバイヤー呼び出し。それは初期統合作業と本番パスのサンドボックススモークテストに十分ですが、コントローラーシードまたはコントローラー強制のシナリオがスコープ内のときはいつでも 部分カバレッジ を生成します。適合性 は、コントローラーによって可能になる完全なライフサイクルウォークである 決定的モード を、完全な専門分野カバレッジのラインとして扱います。 実際には、セラーは通常両方を実行します:
最初の実行は「本番バイヤー可視パスはサンドボックストラフィックを許容するか?」に答えます。2 番目は「ランナーは宣言された専門分野のすべてのライフサイクルパスを証明できるか?」に答えます。それらを 1 つのシグナルに折り畳まないでください。ゼロ失敗の部分実行は有用ですが、バイヤーはどのライフサイクルアサーションがグレードされなかったかを正確に知るためスキップリストが必要です。
comply_test_controller は、3 つのファミリーをカバーする scenario パラメーターを持つ単一のサンドボックス専用ツールです:
シナリオごとのパラメーターとレスポンス形状については コンプライアンステストコントローラーリファレンス を、各専門分野がどのシナリオを要求するかについては Compliance Catalog を参照。
SDK スキャフォールドの配線
@adcp/sdk(6.x が AdCP 3.0 の本番 GA)は createComplyController を出荷し、ツール登録、パラメーター検証、エラーエンベロープ、再シード冪等性を再実装せずにデータ層をコントローラーに配線できます。
スキャフォールドは TypeScript/JavaScript です。Python、Go、Java のセラーは スキーマ に対して直接ツールを実装します — 下のコントラクト(アダプター、エラーコード、冪等性セマンティクス)は同じように適用されます。他言語の SDK は Choose your SDK で追跡されます。
- ツール登録とスキーマ。
controller.toolDefinitionが公開された仕様バージョンと同期のまま。 - ディスパッチと
UNKNOWN_SCENARIO。 登録しないシナリオは自動的にUNKNOWN_SCENARIOを返す — スキーマエラーは決してない。 - パラメーター検証。 無効なパラメーターは、アダプターに到達せずに読める
error_detailを伴うINVALID_PARAMSを生成。 - シード冪等性。 同じ
product_idと等価なfixtureでseed_productを 2 回呼ぶとprevious_state: "existing"を返す。分岐したfixtureはINVALID_PARAMSを返す。アダプターは最初のシードでのみ呼ばれる。 - 型付きエラーエンベロープ。 コントローラーエラーコード表の
codeでTestControllerError(code, message, currentState?)を throw。一般的なアダプターコードは'INVALID_TRANSITION' | 'NOT_FOUND' | 'FORBIDDEN' | 'INVALID_PARAMS'。ダイジェストモードのquery_upstream_traffic実装は、RFC 8785/JCS 正準化が非有限数値に遭遇したときJCS_NON_FINITE_NUMBERも返しうる。
サンドボックスゲーティングの 2 層
スキャフォールドは 2 つのゲートをサポートします。同じプロセスからサンドボックスと本番の両トラフィックを提供する任意のデプロイで両方を出荷してください:- 登録ゲート(主要)。
controller.register(server)を環境チェックでラップ。これがcomply_test_controllerを本番tools/listから完全に外すものです。それなしでは、本番エンドポイントの漏洩したサンドボックス認証情報がセラー側の状態強制を露出します。 - リクエストごとのゲート(多層防御)。
createComplyControllerにsandboxGate: (input) => booleanを渡す。スキャフォールドはすべてのリクエストでそれを呼び、falseを返すときFORBIDDENを返す。ツールが登録されているが一部のリクエストが依然本番アカウントを参照しうる共有プロセスデプロイでこれを使う。
sandboxGate は生のツール入力(Record<string, unknown>)を受け取ります。SDK は auth コンテキストをそれに配管しません — あなたが何を検査するかを決めます。典型的なパターンは、参照されたエンティティ ID を params から引き出し、それが自身のデータ層でサンドボックスアカウントに属することを検証することです:
カスタム MCP ラッパー — リクエストごとの auth の AsyncLocalStorage、トランスポートレベルのサンドボックスゲーティング、セッション裏付けストア — については、
@adcp/sdk/server から低レベルの handleTestControllerRequest、toMcpResponse、TOOL_INPUT_SHAPE を直接合成してください。Step 4 — ストーリーボードランナーを実行
3 つのサーフェスが整ったら、ランナーが引き継ぎます:Avoiding the teach-to-test trap
ストーリーボードはフィクスチャ ID をハードコードします —"test-product"、"campaign_hero_video"、"acmeoutdoor.example"。それらの文字列を特別扱いするコントローラーは、すべての実際のバイヤーで黙って失敗しながらスイートを通過します。それはまさに適合性が防ごうとしている業界コストです: すべての適合性後の統合失敗がセラーの評判を焼き、バイヤーエージェントの懐疑を膨らませ、プロトコル採用を遅らせます。
SDK スキャフォールドは既に正しい方向を指しています: アダプターは product_id、creative_id などを条件ではなく値として受け取ります。アダプターに product_id === "test-product" のスイッチが含まれていたら、後退しています。
2 つの経験則:
- シードシナリオを汎用に実装。
seed_productは任意のproduct_idを受け入れ、その ID でプロダクトをサンドボックスデータ層に永続化する。アダプターはサンドボックスストアに対する実際の upsert の薄いラッパー。 fixtureオブジェクトがコントラクトで、ID はそうでない。 ストーリーボード作者はfixtureをテストが必要とする最小の形状に設定する。それを超えたすべて — ディスカバリー、フィルタリング、認可 — は、本番データで実行するのと同じ方法でフィクスチャシードされたデータで実行される、あなたの通常のコードパス。
準備チェックリスト
最初の完全なストーリーボードスイープの前に:-
get_adcp_capabilitiesが実際に実装するプロトコルと専門分野のみを返す -
account.sandbox: trueが宣言され尊重される — サンドボックスリクエストが実際の支出、本番プラットフォーム呼び出し、永続化された本番状態を生成しない -
sync_accounts(暗黙)またはlist_accounts(明示)がステップ 2 に従いサンドボックスリクエストを扱う -
comply_test_controllerが任意の本番エンドポイントのtools/listから欠如している - 非サンドボックスアカウントを参照するリクエストが
FORBIDDENで拒否される - 主張するストーリーボードが依存するすべてのシードシナリオが、ID 特別扱いなしにフィクスチャを汎用に永続化する
- すべての force シナリオが本番と同じ状態遷移ルールを使い、無効な遷移で型付きエラーを返す
- フィクスチャ ID がランダム UUID にスワップされても完全なストーリーボードスイープが通過する
次は
- エージェントを検証する — CLI、Addie ワークフロー、マルチインスタンス検証
- コンプライアンステストコントローラーリファレンス — 完全なシナリオごとの仕様
- サンドボックスモード — 2 つのアカウントモデルパスを詳しく
- Conformance — 実行が通過したら「conformant」と「verified」が何を意味するか