Skip to content
Open
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
  •  
  •  
  •  
9 changes: 0 additions & 9 deletions .changeset/allow-null-video-delivery-metrics.md

This file was deleted.

6 changes: 0 additions & 6 deletions .changeset/available-actions-non-guaranteed.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/branch-set-cascade-exemption-contract.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/clarify-creative-preflight.md

This file was deleted.

2 changes: 0 additions & 2 deletions .changeset/eighty-snakes-clean.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/fix-compat-fixed-dates.md

This file was deleted.

9 changes: 0 additions & 9 deletions .changeset/fix-creative-storyboard-capability-assertions.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/fix-delivery-buyer-ref-example.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/fix-signal-governance-context.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/governance-human-approval-main.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/preserve-schema-release-status.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/property-list-exclude.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/remove-video-only-inventory-brief.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/withdraw-publisher-domain-filter.md

This file was deleted.

30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
# Changelog

## 3.2.0

### Minor Changes

- 4cdebb9: Allow `null` for video-only delivery metrics (`quartile_data`, `completion_rate`). Sellers running non-video inventory (display, audio-only, DOOH-without-video) legitimately have no value for these metrics, and returning `null` is the correct "not applicable" signal. The schema previously required `type: "number"` / `type: "object"` and rejected `null`, causing receivers to fail validation on every valid display-inventory delivery report.

`delivery-metrics.json` (`totals` / `by_package[]`) now accepts `["number", "null"]` for `completion_rate` and `["object", "null"]` for `quartile_data`; `get-media-buy-delivery-response.json` `aggregated_totals.completion_rate` gets the same loosening so the aggregate path can't re-trigger the failure. The `minimum`/`maximum` constraints on `completion_rate` still apply to non-null values, and the type stays narrowed to null (no strings/arrays). Every other delivery metric continues to signal "not applicable" by omission, not `null` — this exception is scoped to the two video-only fields. Spec-loosening for the receiver contract: producers already sending numbers/objects remain valid.

The separate inline `completion_rate` in `report-plan-outcome-request.json` (a governance self-report block, not on the `get_media_buy_delivery` path) is intentionally left unchanged.

- e75f12f: Add `property_list_exclude` to the targeting overlay: a reference to a property list whose properties must not carry the buyer's ads, for brand-safety do-not-run lists (apps and sites). Mirrors `collection_list_exclude` and reuses `property-list-ref.json`. Exclude wins on overlap with `property_list` and applies regardless of the product's `property_targeting_allowed` flag. Sellers declare support via the property/collection list entries in the `get_adcp_capabilities` targeting table.
- 81cf467: Withdraw the incorrectly specified `publisher_domain` filter from `get_products` before the next minor release. The filter was not patch-eligible for the stable 3.1.x line, and its implementation incorrectly accepted the plural `publisher_domains[]` form that product schemas reject.

### Patch Changes

- 918c073: Runner output contract: document the branch-set `any_of` peer cascade exemption. `cascade_rules` now names a `branch_set_cascade_exemption` (parallel to `sole_stateful_step_exemption`) stating that a stateful peer's genuine failure or `peer_branch_taken` skip MUST NOT cascade `prerequisite_failed` onto a sibling phase sharing the same `branch_set.id` under `any_of` semantics — the peers are mutually-exclusive alternatives, not a dependency chain. The exemption is scoped to `any_of`, is N-ary-safe (any number of peers), leaves cross-set and within-phase cascade unchanged, and is explicitly `depends_on`-agnostic (it fires whether the sibling's dependency is the implicit default or an explicit `depends_on` naming the peer). `storyboard-schema.yaml`'s `depends_on` section gains a cross-reference. Documents-only; codifies the runner behavior shipped in adcp-client#2306 (closing adcp-client#2305), root-caused in adcp#5337. No schema or wire change.
- 4eda22a: Clarify the boundary between `validate_input` manifest preflight and `sync_creatives` dry-run trafficking rehearsal.
- 19a6447: Move stale active-window dates in compliance fixtures and 3.0 compatibility bundles forward so storyboard runs continue to exercise protocol behavior instead of calendar drift.
- c8f3ba5: Fix false failures in creative compliance storyboards (canonical_supported_formats, evaluator_auth).

`canonical_supported_formats`: removes the hardcoded `capability_id: "training_image_generation"` assertion (capability_id is agent-local; any valid value must pass) and the `field_absent` check on `supported_formats[1]` (agents may advertise multiple canonical formats). Fixes `context_outputs` field name from `key:` to `name:`.

`evaluator_auth`: adds `requires_capability` guards to all five optional phases so agents that correctly declare `creative.supports_evaluator: false` receive `not_applicable` instead of failing the evaluator track. Guards evaluate against the raw capabilities response, bypassing a runner-side boolean-false accumulator bug. Fixes `context_outputs` field name from `key:` to `name:`.

- c68d545: Fix a misleading `get_media_buy_delivery` example that implied buyers can look up delivery by their own reference. `media_buy_ids` are seller-assigned; the top-level `buyer_ref` field was removed in 3.0.0. The example is retitled "Correlating Your Own Reference", uses seller-assigned `mb_...` IDs, and adds a note pointing buyers to reconcile their own reference via `context` echoed on `create_media_buy` / `get_media_buys`.
- a335070: Clarify and enforce governed signal activation: `activate_signal` now documents `governance_context`, signal agents fail closed on governed accounts without a valid approval context, and signal governance compliance checks no longer require the signals tenant to own `sync_plans`.
- 24a83c5: Allow governance checks to accept human approval from `ext.human_approval` and use that approval to clear reallocation-threshold human review.
- 348ae53: Preserve withdrawn and unpublished release status when generating file-based schema discovery so exact artifacts remain available without becoming stable alias targets.
- a81067a: Remove an incidental video-only constraint from the inventory list targeting storyboards so single-channel sellers can exercise the channel-agnostic scenarios.

## 3.1.4

### Patch Changes
Expand Down
160 changes: 160 additions & 0 deletions dist/compliance/3.2.0/domains/brand/index.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
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)."
Loading
Loading