Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# Changelog

## 3.2.0-rc.3

### Minor Changes

- f1848ee: Add a shared MediaBuy-level `frequency_cap` (one counter across every package) with `media_buy.aggregate_frequency_capping` seller capability, `Product.media_buy_support` participation, discovery via `required_media_buy_support` and `media_buy_frequency_cap`, the `update_media_buy_frequency_cap` action, and proposal-refinement removal. Scope is determined by field location; package caps are unchanged. `ACTION_NOT_ALLOWED.attempted_action` now references the structured action-id schema so it can name `update_media_buy_frequency_cap`; 3.1 SDKs that validate that field against the flat `media-buy-valid-action` enum should update.
- d44756a: Add structured product frequency-cap constraints (`overlay_support.frequency_cap_support`) and constraint-aware discovery without changing the legacy `frequency_cap: true` boolean, plus package-qualified `update_frequency_caps` availability.
- db1ee5f: Add request-only targeting and product-purchase input schemas for established
and compact create/update surfaces. Each targeting dimension now distinguishes
omission (inherit or preserve), a non-null replacement, and `null` (clear),
while discovery, capability, accepted-commercial-term, and readback schemas
remain strict and non-null.

### Patch Changes

- 8644cdf: Update the TypeScript SDK dependency and current 3.2 RC guidance, certification prompts, conformance metadata, and provenance assertions to `@adcp/sdk@14.0.0-rc.35`.
- acab756: Harden the experimental Reliable Reporting consumer-status loop. Reserve `authoritative_party` on `reporting-delivery-config.json` (sellers MUST reject `consumer` with `UNSUPPORTED_FEATURE` until a later minor defines the buyer-deposited revision task) and relax the seller-authoritative billing-feed constraint accordingly. Give a `received` status made stale only by a seller restatement a bounded `delayed` grace window before it escalates. Make the buyer's posting deadline `expected_at + automated_recovery_window_seconds` and surface unmet deadlines through `obligation_counts.consumer_status_pending`, a count that never changes seller health. Add issue lifecycle fields (`opened_at`, `issue_state`, `external_ref`) with optional `consumer_mismatch_escalation_seconds` and `operations_contact` capability advertisement. Add the `content_mismatch` consumer status with a closed `mismatch_code` for contract-fact disagreements, which are explicitly not measurement disputes. Extend the `reporting_core_lifecycle_probe` controller with `restate_after_received` so the grace projection is graded live, and make the reference seller reject the reserved `authoritative_party` value so the normative MUST has working code behind it.
- decd95f: Retire superseded 3.x beta prerelease artifacts from `dist/schemas`, `dist/compliance`, and `dist/protocol`, keeping only the `3.2.0-beta.11` schema bundle (frozen `3.2-beta` documentation selector), `3.2.0-beta.6` (the training agent's retained checkpoint), and `3.1.0-beta.7` (the TypeScript SDK side bundle). This removes about 2 GB from the repository and the runtime image, whose size gate the rc.3 release branch had started to exceed. Previously published beta URLs continue to be served from the artifact CDN on a best-effort basis; documentation now links to the `3.2.0-rc.2` bundle. The immutable-release-artifact guard now permits whole-tree deletion of tagged beta checkpoints while still rejecting in-place edits and any deletion of release-candidate or stable artifacts.
- 8d50c0e: `scripts/run-storyboards-matrix.sh` snapshots the freshly built `dist/schemas/latest` into a temporary directory and runs every tenant against that copy, so a concurrent `npm run build:schemas` in the same tree can no longer abort a tenant with the SDK's schema-root version mismatch. The pre-push hook treats the local matrix as advisory: it is skipped when the working tree has uncommitted changes or when `ADCP_SKIP_STORYBOARD_MATRIX=1`, with the `training-agent-storyboards.yml` workflow as the authoritative gate.
- 322e39c: Update the pinned Changesets release action to v2.1.2 and refresh its vendored contract fixture and release-workflow verification.

## 3.2.0-rc.2

### Minor Changes
Expand Down
196 changes: 196 additions & 0 deletions dist/compliance/3.2.0-rc.3/domains/brand/index.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
id: brand_baseline
version: "1.0.0"
title: "Brand baseline"
protocol: brand
category: brand_baseline
summary: "Baseline protocol storyboard — every brand agent must declare the brand protocol in capabilities and return a schema-valid brand identity."
track: brand
required_tools:
- get_brand_identity

narrative: |
Brand protocol agents are the identity layer of AdCP. Their job is to hold
brand identity data (names, logos, colors, fonts, tone) and expose it to
other agents — buyer agents, creative agents, DSPs — that need to render
on-brand creative or verify who a campaign is for.

The baseline tests the minimum contract that every brand agent honors,
regardless of what additional capabilities (rights licensing, creative
approval) it layers on top:

1. Declare `brand` in `supported_protocols` on `get_adcp_capabilities`.
2. Respond to `get_brand_identity` with a schema-valid identity manifest.
3. Reject unknown `brand_id` values with a structured error.

Rights licensing (`get_rights`, `acquire_rights`, `update_rights`,
`creative_approval`) ships experimentally in 3.0 and is covered by the
`brand-rights` specialism storyboard, not this baseline.

agent:
interaction_model: brand_agent
capabilities: []
examples:
- "Any brand agent (simple identity host or full rights platform)"
- "Brand-owned agents (Acme Outdoor)"
- "Third-party brand identity platforms"
- "Agency-hosted brand agents"

caller:
role: buyer_agent
example: "Any buyer, creative agent, or DSP needing brand identity"

prerequisites:
description: |
The test kit provides a sample brand (Nova Motors) that any brand agent
can serve identity for.
test_kit: "test-kits/nova-motors.yaml"

phases:
- id: capability_discovery
title: "Capability discovery"
narrative: |
The buyer calls `get_adcp_capabilities` to confirm the agent declares
the brand protocol before issuing any brand-identity call.

steps:
- id: get_capabilities
title: "Check agent capabilities"
narrative: |
Verify that the agent declares `brand` in `supported_protocols`.
Without this claim the buyer MUST NOT send `get_brand_identity`.
task: get_adcp_capabilities
schema_ref: "protocol/get-adcp-capabilities-request.json"
response_schema_ref: "protocol/get-adcp-capabilities-response.json"
doc_ref: "/protocol/get_adcp_capabilities"
comply_scenario: capability_discovery
stateful: false
expected: |
Return capabilities declaring `brand` in `supported_protocols`.

sample_request:
context:
correlation_id: "brand_baseline--get_capabilities"
validations:
- check: response_schema
description: "Response matches get-adcp-capabilities-response.json schema"
- check: field_present
path: "supported_protocols"
description: "Response declares supported_protocols"

- id: brand_identity_retrieval
title: "Brand identity retrieval"
narrative: |
The buyer calls `get_brand_identity` to retrieve the brand's identity
manifest. The minimum contract is a schema-valid response that echoes
the requested `brand_id` and carries at least one name.

steps:
- id: get_brand_identity
title: "Retrieve brand identity"
narrative: |
The buyer calls `get_brand_identity` with a known `brand_id`. The
response MUST match the brand-identity schema and echo the
requested `brand_id`. Rich fields (logos, colors, fonts, tone,
visual_guidelines) are optional at the baseline level — the
minimum bar is that identity resolution works and is schema-valid.
task: get_brand_identity
schema_ref: "brand/get-brand-identity-request.json"
response_schema_ref: "brand/get-brand-identity-response.json"
doc_ref: "/brand-protocol/tasks/get_brand_identity"
stateful: false
expected: |
Return a schema-valid brand identity that echoes the requested
brand_id and includes at least one name.

sample_request:
brand_id: "nova_motors"
context:
correlation_id: "brand_baseline--get_brand_identity"
context_outputs:
- path: "brand_id"
key: "brand_id"

validations:
- check: response_schema
description: "Response matches get-brand-identity-response.json schema"
- check: field_present
path: "brand_id"
description: "Response includes brand_id"
- check: field_value
path: "brand_id"
value: "nova_motors"
description: "Returned brand_id echoes the requested brand"
- check: field_present
path: "names"
description: "Response includes brand names"

- id: unknown_brand_rejection
title: "Unknown brand rejection"
narrative: |
Agents MUST reject unknown `brand_id` values with a structured
AdCP error rather than returning an empty or fabricated manifest.

steps:
- id: get_brand_identity_unknown
title: "Reject unknown brand ID"
narrative: |
The buyer calls `get_brand_identity` with a `brand_id` the agent
does not serve. The response MUST be a structured error with a
recovery classification — not a success response with empty
fields.
task: get_brand_identity
schema_ref: "brand/get-brand-identity-request.json"
response_schema_ref: "brand/get-brand-identity-response.json"
doc_ref: "/brand-protocol/tasks/get_brand_identity"
stateful: false
expected: |
Return an AdCP error response indicating the brand is not known
to this agent.

sample_request:
brand_id: "brand_that_does_not_exist_12345"
context:
correlation_id: "brand_baseline--get_brand_identity_unknown"

expect_error: true
negative_path: payload_well_formed
validations:
- check: error_code
value: "REFERENCE_NOT_FOUND"
description: "Error code indicates brand-not-found. REFERENCE_NOT_FOUND is the canonical fallback per error-handling.mdx (brands lack a dedicated *_NOT_FOUND code)."

- id: brand_discovery
title: "Optional brand discovery"
narrative: |
Agents that implement the experimental `search_brands` task expose a
schema-valid discovery surface without making that task part of the
baseline brand protocol requirement.

steps:
- id: search_brands
title: "Search the agent's brand roster"
task: search_brands
schema_ref: "brand/search-brands-request.json"
response_schema_ref: "brand/search-brands-response.json"
doc_ref: "/brand-protocol/tasks/search_brands"
comply_scenario: brand_discovery
requires_tool: search_brands
stateful: false
expected: |
Return a schema-valid ranked array of brand stubs. An empty array is
valid when the agent has no matching roster entry.
sample_request:
query: "automotive brands with electric vehicles"
countries: ["US"]
context:
correlation_id: "brand_baseline--search_brands"
validations:
- check: response_schema
description: "Response matches search-brands-response.json schema"
- check: field_present
path: "brands"
description: "Discovery response includes the brands array"
- check: field_value
path: "context.correlation_id"
value: "brand_baseline--search_brands"
description: "Context correlation_id returned unchanged"
Loading
Loading