Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
6503c70
fix(security): make get_products retry-safe
bokelley Jul 30, 2026
5d96da3
fix(ci): preserve 3.0 get_products compatibility
bokelley Jul 30, 2026
60068ad
fix(ci): update get_products storyboards
bokelley Aug 9, 2026
7714893
fix(ci): persist in-process training mutations
bokelley Aug 9, 2026
7034689
fix(security): fence get_products retries
bokelley Aug 9, 2026
b89def5
fix(ci): preserve scoped compliance fixtures
bokelley Aug 9, 2026
e1ae78a
fix(ci): preserve 3.0 session routing
bokelley Aug 9, 2026
352b9e9
fix(ci): align current account transport
bokelley Aug 9, 2026
fe17f4e
fix(training): allow concurrent product discovery
bokelley Aug 9, 2026
2033037
merge main into security-wave-12-get-products-idempotency
bokelley Aug 9, 2026
d5b0a59
Merge remote-tracking branch 'origin/main' into clean-up-pr-6115
bokelley Aug 9, 2026
2a78ebf
fix(protocol): move get_products idempotency to 4.0
bokelley Aug 10, 2026
823b65b
feat(media-buy): split product discovery tools for 3.2
bokelley Aug 10, 2026
f9074e0
Merge remote-tracking branch 'origin/main' into clean-up-pr-6115
bokelley Aug 10, 2026
0e55223
docs(media-buy): add SEO metadata for split tools
bokelley Aug 10, 2026
3725a97
docs(media-buy): pin split tool schema links to v3
bokelley Aug 10, 2026
7fc4146
fix(media-buy): register split tools in tenant catalogs
bokelley Aug 10, 2026
937c4bf
test(media-buy): check each 3.0 catalog exclusion
bokelley Aug 10, 2026
c596386
feat(media-buy): define compact proposal lifecycle
bokelley Aug 10, 2026
99bfd48
fix(media-buy): close split lifecycle contract gaps
bokelley Aug 10, 2026
7581d97
fix(media-buy): project split lifecycle webhooks
bokelley Aug 10, 2026
cc4c246
Merge origin/main into clean-up-pr-6115
bokelley Aug 10, 2026
0b61d49
fix(training): preserve storyboard fixture isolation
bokelley Aug 10, 2026
fd808b4
Merge remote-tracking branch 'origin/main' into clean-up-pr-6115
bokelley Aug 10, 2026
9d27ef9
test(media-buy): remove duplicate brand fixture
bokelley Aug 10, 2026
fad366a
docs(media-buy): use stable schema aliases
bokelley Aug 11, 2026
f63de06
fix(schema): discriminate proposal lifecycle responses
bokelley Aug 11, 2026
f047bef
docs(media-buy): clarify split lifecycle responses
bokelley Aug 11, 2026
ca7ed45
test(media-buy): align split task schema assertions
bokelley Aug 11, 2026
b996428
feat(media-buy): add opportunity proposal lifecycle
bokelley Aug 11, 2026
6184a0a
docs(media-buy): pin decline proposal schema link
bokelley Aug 11, 2026
4539e73
test(media-buy): classify proposal decline scope
bokelley Aug 11, 2026
bd6cf6e
refactor(media-buy): simplify proposal lifecycle
bokelley Aug 11, 2026
0d4c13e
feat(protocol): make task results SDK-resolvable
bokelley Aug 11, 2026
d45fce1
docs(protocol): pin manifest link to v3
bokelley Aug 11, 2026
452b2ff
docs(protocol): describe generated manifest artifact
bokelley Aug 11, 2026
45f3b0e
fix(build): avoid task schema validation race
bokelley Aug 11, 2026
6568b78
Merge remote-tracking branch 'origin/main' into clean-up-pr-6115
bokelley Aug 12, 2026
3c90671
Merge remote-tracking branch 'origin/main' into clean-up-pr-6115
bokelley Aug 12, 2026
e15d65e
keep proposal inputs provenance-free
bokelley Aug 12, 2026
58bf79a
keep split product tools canonical-only
bokelley Aug 12, 2026
2f874aa
Merge remote-tracking branch 'origin/main' into clean-up-pr-6115
bokelley Aug 12, 2026
6c033ba
fix(media-buy): address review findings from PR #6115
claude Aug 12, 2026
5d6eac0
feat(media-buy): add compact 3.2 lifecycle
bokelley Aug 12, 2026
d1faf2b
Merge remote-tracking branch 'origin/security-wave-12-get-products-id…
bokelley Aug 12, 2026
203ef2a
fix(docs): pin compact lifecycle schema links
bokelley Aug 12, 2026
44cb3f5
fix(media-buy): align compact runtime and completion fixtures
bokelley Aug 12, 2026
041bcf0
feat(schemas): add active MCP role catalogs
bokelley Aug 12, 2026
57aa539
Merge remote-tracking branch 'origin/main' into clean-up-pr-6115
bokelley Aug 12, 2026
17a03ca
fix(media-buy): restore proposal inventory holds
bokelley Aug 12, 2026
d619981
Merge remote-tracking branch 'origin/main' into clean-up-pr-6115
bokelley Aug 12, 2026
4deaa09
fix(media-buy): discriminate proposal refinements
bokelley Aug 12, 2026
792c0e9
feat: scope brand and operator account identities
bokelley Aug 13, 2026
e4b75cb
Merge remote-tracking branch 'origin/main' into clean-up-pr-6115
bokelley Aug 13, 2026
d5f5c3d
test: preserve sandbox account identity in webhook flows
bokelley Aug 13, 2026
acfe841
fix(schema): extend MULTI_FINALIZE_UNSUPPORTED to cover refine_propos…
bokelley Aug 13, 2026
2534a1a
docs: refresh generated compliance error codes
bokelley Aug 13, 2026
637fbd7
feat(accounts): define advertiser account keys
bokelley Aug 14, 2026
659fcad
Merge remote-tracking branch 'origin/main' into clean-up-pr-6115
bokelley Aug 14, 2026
7f3c13c
feat(accounts): define advertiser account currency modes
bokelley Aug 14, 2026
6af26d4
test(accounts): update currency capability fixtures
bokelley Aug 14, 2026
d375881
fix(accounts): preserve 3.1 capability compatibility
bokelley Aug 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .agents/sdk-shim-ledger.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@
"owner": "compliance",
"upstream": "adcontextprotocol/adcp-client#2105",
"problem": "The SDK package ships a snapshot of compliance bundles, schema bundles, and generated validators. Current PR storyboard runs need to grade current repo source before a new protocol bundle exists.",
"localBehavior": "Build current compliance/schema bundles, copy them into the SDK cache, and patch generated validators for same-PR controller enums and request/response schema additions.",
"localBehavior": "Build current compliance/schema bundles, copy them into the SDK cache, and patch generated validators for same-PR controller enums and request/response schema additions. The patch regression suite also loads the installed generated response validator to prove the additive account response remains consumable by the pinned 3.1 SDK.",
"releaseFollowUp": "This overlay is validation-only and does not publish generated types. After the protocol release, regenerate and publish @adcp/sdk, then explicitly upgrade pinned downstream consumers including agentic-api.",
"removalCondition": "Remove when the storyboard matrix passes current compliance and schema roots through public SDK options instead of overlaying the SDK cache.",
"paths": [
"scripts/overlay-compliance-cache.sh",
"scripts/run-storyboards-matrix.sh"
"scripts/run-storyboards-matrix.sh",
"tests/patch-sdk-rc15.test.cjs"
],
"terms": [
"node_modules/@adcp/sdk/compliance/cache",
Expand Down
1 change: 1 addition & 0 deletions .changeset/secure-get-products-idempotency.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
Add the compact AdCP 3.2 product and MediaBuy lifecycle: `list_products`, `request_proposals`, `refine_proposals`, `decline_proposals`, `buy_products`, `accept_proposal`, and `control_media_buy`. The task-specific contracts separate offer discovery, immutable draft proposal creation, explicit finalization with inventory reservation, terminal decline, direct purchase, proposal acceptance, and operational delivery control while retaining `get_products`, `create_media_buy`, and `update_media_buy` as compatibility facades throughout 3.x. New purchase and control inputs never accept inline creatives; commercial amendments and negotiated cancellations fork an accepted proposal, while operational controls remain revision-checked. Compact purchase snapshots preserve resolved package flight, billing-measurement, performance, and reporting terms. A shared opportunity reference connects planning-cycle context through purchase without duplicating proposal version identity. Canonical inputs use stable brand keys, catalog references, and compact account and optimization types so brand assets, legacy named formats, creative provenance, and compliance payloads do not transitively enter the clean tools. Publish machine-readable SDK fallback grades and task-result schema resolution, plus MCP production, media-buy, and creative catalogs that remove presentation annotations without changing validation semantics. The role catalogs select active 3.2 seller-hosted operations and publish client-side input-only prompt views while retaining output and terminal task-result schemas in their parent validation catalogs.

Preserve the AdCP 3.1 inventory-reservation contract in the compact lifecycle: requested and revised proposals remain immutable drafts until `refine_proposals` finalizes them, and a finalized `committed` snapshot guarantees inventory is held until `expires_at`. Add `countries` and `property_list` product-attribute filters, and publish compact task-specific async envelopes for consultative proposal planning and re-underwriting.
Let compact BrandKeys qualify commercial advertiser identity with canonical `countries[]` without turning identity into delivery targeting. Extend buyer-declared natural accounts with an operator-owned unit (`id` plus mutable display `name`), optional immutable account currency, and sandbox identity. These fields round-trip through `sync_accounts` and `list_accounts`; the operator unit remains explicitly distinct from the seller/storefront `account_id`. Require sellers implementing 3.2 advertiser-account provisioning to advertise fixed versus per-media-buy account currency support while keeping the additive field optional on the shared 3.x response schema for 3.1 compatibility, and define only the BrandKey projection of a compatibility BrandRef as account identity.
9 changes: 6 additions & 3 deletions docs/accounts/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Seven questions underlie every AdCP transaction:
| How does the operator authenticate? | Seller capabilities | `require_operator_auth` determines who must authenticate and which account reference shape is expected. |
| What am I allowed to do on this account? | Caller scope | The `authorization` object on each per-account entry in [`sync_accounts`](/docs/accounts/tasks/sync_accounts) and [`list_accounts`](/docs/accounts/tasks/list_accounts) responses describes `allowed_tasks`, `field_scopes`, `scope_name`, and `read_only` for the calling agent. See [Caller authorization](#caller-authorization) below. |
| Who gets billed? | Account terms | Buyer passes `billing` in `sync_accounts` — `operator`, `agent`, or `advertiser` — when a choice is needed. A lazy-provisioning seller uses an unambiguous capability or onboarding default. |
| Where is currency selected? | Seller capabilities | `supported_account_currency_modes` declares whether `currency` is fixed on the advertiser account, selected per media buy, or both. |
| What was consumed? | Usage reporting | `report_usage` informs vendor agents how their services were used after delivery |

The seller declares the account model in [`get_adcp_capabilities`](/docs/protocol/get_adcp_capabilities) via `require_operator_auth`. That field declares who must authenticate; it does not by itself declare whether OAuth is used, whether `list_accounts` is exposed, or which `sync_accounts` modes are supported.
Expand All @@ -43,7 +44,9 @@ The Accounts Protocol applies across all vendor protocols. An orchestrator estab
| Governance | Content standards billing |
| Creative | Creative service billing |

The account reference may be a seller-assigned `account_id` (seller-owned namespaces, usually `require_operator_auth: true`) or a natural key — `brand` + `operator` (buyer-declared accounts, `require_operator_auth: false`). For buyer-declared accounts, the natural-key `AccountRef` MUST remain valid on subsequent calls even if the seller also echoes an internal `account_id`. For sandbox, account-id namespaces use pre-existing test accounts discovered via `list_accounts` or supplied out-of-band. Buyer-declared accounts use `sandbox: true` in `sync_accounts`, or in the natural-key `AccountRef` when a lazy-provisioning seller declares sandbox support and needs no other buyer-supplied setup. See [Account references](/docs/building/by-layer/L2/accounts-and-agents#account-references) for details.
The account reference may be a seller/storefront-assigned `account_id` (seller-owned namespaces, usually `require_operator_auth: true`) or a buyer-declared advertiser key — `brand` + `operator` + optional `operator_unit`, `currency`, and `sandbox` (`require_operator_auth: false`). In this vocabulary, **brand identity** is the BrandKey projection (`domain`, optional `brand_id`, canonicalized `countries[]`); **operator identity** is the operator domain plus optional `operator_unit.id`; and **advertiser account identity** is the complete natural key, including currency and sandbox disposition. Mutable `operator_unit.name` and broader BrandRef overrides are not identity. `operator_unit.id` is deliberately separate from the seller's `account_id`. For buyer-declared accounts, the complete natural-key `AccountRef` MUST remain valid on subsequent calls and round-trip through `list_accounts`, even if the seller also echoes an internal `account_id`. See [Account references](/docs/building/by-layer/L2/accounts-and-agents#account-references) for details.

`billing` names the party the seller invoices for this account relationship. It is not a payment rail or settlement selector. AdCP does not currently standardize per-media-buy choice between an intermediary clearing flow and direct settlement; implementations must not encode that distinction by silently changing the meaning of `billing`.

## Account Status Lifecycle

Expand Down Expand Up @@ -289,14 +292,14 @@ The Accounts Protocol operates with four party types. See [Accounts and agents](

| Party | Role | Identified by |
| ------------ | ----------------------------- | --------------------------------------------------------- |
| Brand | Whose products are advertised | `brand.domain` + optional `brand.brand_id` via brand.json |
| Brand | Whose products are advertised | `brand.domain` + optional `brand.brand_id`/`brand.countries[]` via brand.json |
| Operator | Who drives the buys | Domain (e.g., `pinnacle-media.com`) |
| Agent | What software places the buys | Authenticated session |
| Vendor agent | The seller's AdCP agent | `agent_url` |

## Tasks

**Account discovery (normative).** Every agent accepting accounts MUST expose at least one of `list_accounts` or `sync_accounts`. A seller-defined account-id namespace MAY omit both only when account IDs are supplied out-of-band and no account settings are managed through AdCP. Buyer-declared-account sellers normally expose `sync_accounts` to establish the relationship and SHOULD also expose `list_accounts` for cold-start recovery. A buyer-declared seller MAY omit `sync_accounts` only when it lazily provisions from the natural key, can resolve every required setting without buyer input, and exposes `list_accounts`; this makes auto-provisioning plus a read-only `list_accounts` conformant for that narrow case. For account-id namespaces, `sync_accounts` is settings-update only in 3.0.x unless a future explicit capability declares account-id provisioning. See [Required tasks by protocol](/docs/protocol/required-tasks#any-agent-accepting-accounts).
**Account discovery (normative).** Every agent accepting accounts MUST expose at least one of `list_accounts` or `sync_accounts`. A seller-defined account-id namespace MAY omit both only when account IDs are supplied out-of-band and no account settings are managed through AdCP. Buyer-declared-account sellers normally expose `sync_accounts` to establish the relationship and SHOULD also expose `list_accounts` for cold-start recovery: a stateless buyer cannot reconstruct lost advertiser natural keys by replaying `sync_accounts`. `list_accounts` therefore returns the brand, operator, and optional operator unit, currency, and sandbox fields needed to compose the reference again. A buyer-declared seller MAY omit `sync_accounts` only when it lazily provisions from the complete natural key, can resolve every required setting without buyer input, and exposes `list_accounts`. For account-id namespaces, `sync_accounts` is settings-update only in 3.0.x unless a future explicit capability declares account-id provisioning. See [Required tasks by protocol](/docs/protocol/required-tasks#any-agent-accepting-accounts).

| Task | Purpose |
| ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
Expand Down
3 changes: 2 additions & 1 deletion docs/accounts/provisioning-walkthrough.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ Sam calls `get_adcp_capabilities` before choosing an account workflow. The relev
"account": {
"require_operator_auth": false,
"supported_billing": ["operator", "agent", "advertiser"],
"supported_account_currency_modes": ["fixed", "per_media_buy"],
"notifications": {
"supported": true,
"registration_task": "sync_accounts",
Expand All @@ -97,7 +98,7 @@ Sam calls `get_adcp_capabilities` before choosing an account workflow. The relev
}
```

`require_operator_auth: false` selects buyer-declared provisioning. `supported_billing` tells Sam which billing values the seller accepts at the capability level; it does not guarantee that every authenticated buyer agent is commercially authorized for every advertised value.
`require_operator_auth: false` selects buyer-declared provisioning. `supported_billing` tells Sam which invoiced parties the seller accepts at the capability level; it does not guarantee that every authenticated buyer agent is commercially authorized for every advertised value. `supported_account_currency_modes` tells Sam whether to include one immutable account `currency`, omit it for per-media-buy selection, or choose either model.

The `notifications` block selects the preferred observation strategy: register a durable subscriber during provisioning, treat each webhook as an invalidation signal, and repair from `list_accounts`. If the block is absent or `supported` is `false`, poll instead.

Expand Down
Loading
Loading