TL;DR
| What it is | Where it lives | Normative? | |
|---|---|---|---|
| Storyboards | YAML files defining a workflow end-to-end + every wire-shape assertion. The conformance specification. | /compliance/{version}/universal/*.yaml, protocols/*/*.yaml, specialisms/*/index.yaml | ✅ Yes |
comply_test_controller scenarios | Protocol-level tool operations a seller exposes (force_*, simulate_*, seed_*) so storyboards can drive deterministic state. | The scenario parameter of the seller’s comply_test_controller MCP tool. | ✅ Yes |
@adcp/sdk/testing/scenarios/*.ts | Legacy TypeScript test runners predating storyboard-driven comply(). | node_modules/@adcp/sdk/dist/lib/testing/scenarios/*.js | ❌ No |
node_modules/@adcp/sdk/dist/lib/testing/scenarios/media-buy.js and trying to figure out what AdCP requires — stop. That’s not the spec. Read the storyboards instead.
Storyboards (normative)
Storyboards are the conformance specification. Each one defines:- A workflow (e.g. sales-guaranteed proposal/refine/finalize lifecycle)
- The exact tool calls a buyer agent makes
- Every wire-shape assertion the seller’s responses must satisfy
- The
comply_test_controlleroperations the runner uses to seed deterministic state
conformance.mdx calls these “the truth” — and means it. These YAML files are the basis for AgenticAdvertising.org Verified (Spec); AgenticAdvertising.org issues that qualifier when its compliance heartbeat runs the applicable storyboards and every assertion passes.
You’ll see storyboards at:
/compliance/{version}/universal/*.yaml— every AdCP agent must pass/compliance/{version}/protocols/{protocol}/index.yaml— anyone claiming the protocol/compliance/{version}/specialisms/{id}/index.yaml— opt-in claims
npx @adcp/sdk@latest storyboard run <id> or interactively through Addie.
Source authority and rollout
The authored source of truth for storyboards isstatic/compliance/source/ in the adcontextprotocol/adcp repo. scripts/build-compliance.cjs builds dist/compliance/latest/ during development and stamps dist/compliance/{version}/ on release, adding only generated distribution artifacts such as index.json and the legacy domains/ alias. SDKs may bundle a snapshot so runners work offline and remain version-pinned, but that snapshot is a distribution copy, not the authority.
During the current migration, @adcp/sdk still loads its bundled cache by default. Spec repo CI overlays static/compliance/source/ onto that cache before running the training-agent storyboards so pull requests are graded against the candidate source without switching runtime authority in the same step. SDK release work should separately prove its bundled cache matches the spec bundle it claims to ship.
Breaking or materially stricter storyboard changes must roll out in this order:
comply_test_controller scenarios (normative — but different)
The word “scenario” also appears in the comply_test_controller MCP tool that sellers expose to support deterministic testing. Storyboards call this tool with scenario: <name> to drive seller state without waiting for real time to pass: e.g. force_task_completion to finish a pending async media buy, simulate_delivery to inject impressions, seed_product to install a fixture.
These are protocol operations, not test runners. They’re documented at comply_test_controller. Sellers MUST implement them to be testable; the storyboards MUST use them to stay deterministic.
So when you hear “the seller doesn’t support that scenario,” it usually means: “the seller’s comply_test_controller doesn’t expose force_X yet.” Not “no storyboard tests X.”
@adcp/sdk/testing/scenarios/*.ts (NON-normative legacy)
The SDK ships TypeScript files under testing/scenarios/ — media-buy.ts, signals.ts, creative.ts, and a dozen siblings. These predate the storyboard-driven comply() engine. They are:
- Not the conformance spec. Reading them to learn what AdCP requires will produce wrong answers.
- Not maintained in lockstep with storyboards. A scenario file may hard-code parameters that the storyboard equivalent has long since corrected. Example:
scenarios/media-buy.tshard-codesbuying_mode: 'brief'at four call sites; the YAML storyboard forsales-guaranteedexercisesbuying_mode: 'refine'+action: 'finalize'via theproposal_finalizestoryboard. Both are validbuying_modevalues; the scenario file just doesn’t cover the lifecycle. - Callable, but for different purposes. Internal smoke tests in the SDK, integration-test fixtures for downstream tooling, and some legacy paths still use these. They are not what AgenticAdvertising.org Verified (Spec) runs against.
testing/scenarios/*.ts to understand AdCP, you’ve taken a wrong turn. The right path:
- Find the storyboard that matches your declared specialism:
npx @adcp/sdk@latest storyboard list - Read the YAML:
npx @adcp/sdk@latest storyboard show <id> - Run it:
npx @adcp/sdk@latest storyboard run <id> --agent-url <url>
Three-line decoder
| If you see… | …you’re looking at | Trust as spec? |
|---|---|---|
A .yaml under /compliance/{version}/... | A storyboard | ✅ Yes |
A seller responding to comply_test_controller with a scenario parameter | A protocol-level test-control operation | ✅ Yes (the contract is normative; the seller MAY refuse with UNKNOWN_SCENARIO) |
A .ts or .js under @adcp/sdk/dist/lib/testing/scenarios/ | A legacy SDK test runner | ❌ No |
Cross-repo
The disambiguation work in the SDK itself — marking the legacy scenarios as@deprecated, mirroring the storyboard CLI verbs, or removing the export entirely — lives in adcp-client. The decision on whether testing/scenarios/* stays public-but-deprecated or becomes internal-only is tracked in #4035.
For now: if you want to test an AdCP agent, the answer is storyboards. The other two things named “scenario” have their place, but they aren’t it.