Skip to content

feat: propagation_surfaces array + rejection_reason on get_media_buys (#4686, #4687)#4690

Merged
bokelley merged 3 commits into
mainfrom
bokelley/v3-1-0-followups-round-2
May 18, 2026
Merged

feat: propagation_surfaces array + rejection_reason on get_media_buys (#4686, #4687)#4690
bokelley merged 3 commits into
mainfrom
bokelley/v3-1-0-followups-round-2

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Two 3.1.0 follow-ups from the #4685 expert-review batch — both addressing taxonomy/schema gaps before 3.1.0 GA (2026-05-29).

Issues closed

Commits

  1. feat(media-buy): restructure impairment_propagation as propagation_surfaces array (#4686)

    • Replaces single-value enum capabilities.media_buy.impairment_propagation with non-exclusive array capabilities.media_buy.propagation_surfaces. The enum forced a choice between snapshot and webhook_only, but the common case is both — GAM, FreeWheel, CM360 mirror impairments on the buy snapshot AND fire webhooks. The previous shape created an incentive to declare webhook_only to dodge the snapshot-coherence bar. The array lets sellers declare ["snapshot", "webhook"] honestly.
    • Surface values: snapshot (graded by impairment.coherence storyboards), webhook (graded by webhook contract), out_of_band (offline agreement, not protocol-graded).
    • Default when absent: ["snapshot"] — preserves current behavior for sellers that don't declare.
    • Storyboard gating: scenarios grade not_applicable when propagation_surfaces does not include "snapshot".
    • Documents the out_of_band semantic split: sellers with a mapping gap (data in API under a non-AdCP field name) SHOULD document the mapping rather than claim out_of_band.
    • Pre-release breaking change to the freshly-shipped enum in feat: 3.1.0 follow-ups — impairment_propagation, swap recovery, cardinality #4685 — 3.1.0 hasn't released yet (GA 2026-05-29), so no deprecation cycle needed.
  2. fix(media-buy): surface rejection_reason on get_media_buys response items (#4687)

    • Adds rejection_reason to get-media-buys-response.json#/properties/media_buys/items/properties — same gap-class as health + impairments[] fixed in feat: 3.1.0 follow-ups — impairment_propagation, swap recovery, cardinality #4685.
    • Completes the audit of core/media-buy.json against the response schema. Every other field on core/media-buy.json is already mirrored on the response items. After this patch, the response is complete with respect to canonical media-buy fields.

One minor changeset (#4686, pre-release-breaking but additive in semantics) + one patch changeset (#4687).

Test plan

  • build:schemas ✓ / build:compliance
  • test:schemas ✓ / test:examples
  • test:storyboard-validations-paths ✓ (only pre-existing brand-rights failure unchanged)
  • test:storyboard-{doc-parity,check-enum,branch-sets,test-kits,sample-request-schema,response-schema,context-entity,contradictions,provides-state-for,auth-shape,advisory-expiry,raw-mode-required}
  • Pre-push storyboard matrix ✓ — both scenarios run cleanly across all six tenants
  • CI green

Rollout

  • propagation_surfaces defaults to ["snapshot"] when absent — pre-3.1 sellers continue to be graded on snapshot coherence as today.
  • Sellers who already adopted the pre-release impairment_propagation enum migrate single values to one-element arrays — five-second translation.
  • Runtime gating in the compliance runner (read propagation_surfaces, grade not_applicable when "snapshot" is absent) is the adcp-client follow-up (adcp-client#1830 covers the related array_length check kind).

🤖 Generated with Claude Code

bokelley and others added 3 commits May 17, 2026 18:57
…rfaces array (#4686)

Replace the single-value enum capabilities.media_buy.impairment_propagation
with the non-exclusive array capabilities.media_buy.propagation_surfaces.
The enum couldn't express the common case where a seller propagates on both
the buy snapshot AND fires webhooks — premium guaranteed sellers (GAM,
FreeWheel, CM360) do both, but the previous enum forced a choice between
'snapshot' and 'webhook_only', creating an incentive to declare
'webhook_only' and dodge the snapshot-coherence bar.

Surface values:
  snapshot    — media_buy.health + impairments[] mirror on get_media_buys
  webhook     — notification-type: impairment fires via
                push_notification_config
  out_of_band — channels outside AdCP entirely (email, dashboard,
                partner-specific feeds)

Default when absent: ['snapshot']. Storyboard gating: scenarios grade
not_applicable when propagation_surfaces does not include 'snapshot'.

Pre-release breaking change — the original enum landed in #4685 but
3.1.0 hasn't released yet (GA 2026-05-29), so no deprecation cycle.

Also documents the out_of_band semantic split (proper out-of-band vs
mapping-gap-disguised-as-out-of-band) and prescribes documenting mappings
rather than claiming out_of_band when the seller does have the data
under a non-AdCP field name.

Closes #4686.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tems (#4687)

The field existed on core/media-buy.json but wasn't typed on the
get-media-buys-response.json items — same gap-class as health +
impairments[] fixed in #4685.

Completed the full audit of core/media-buy.json against the response
schema: every other field (media_buy_id, account, status, health,
impairments, confirmed_at, cancellation, total_budget, packages,
invoice_recipient, creative_deadline, revision, created_at, updated_at,
ext) is already mirrored. With rejection_reason added, the response is
complete with respect to the canonical media-buy fields. Response-only
fields (currency, start_time, end_time, valid_actions,
available_actions, history, augmented packages with delivery snapshots)
remain — deliberately response-side, not on core/media-buy.json.

Closes #4687.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three expert reviews (protocol, docs, product). Must-fix items:

- Drop real-brand names from schema description and lifecycle.mdx
  (GAM/FreeWheel/CM360). Replaced with 'premium guaranteed sellers'
  generic descriptor. Playbook rule (no real brands in examples).

- Add explicit 'empty array invalid' clarification to the
  propagation_surfaces description — minItems: 1 already enforces it,
  but readers don't always check the constraint block.

- Fix stale adcp#4683 referent in dependency_impairment.yaml — the
  capability is no longer in #4683's shape; lifecycle.mdx is the live
  cross-reference and is sufficient on its own.

Deferred (filed separately):
- proprietary_field guidance follow-up so the description's SHOULD
  directive doesn't get lost.
- Release notes callout for the value rename webhook_only → webhook in
  3.1.0 GA notes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bokelley bokelley merged commit 4d4c9a0 into main May 18, 2026
24 checks passed
@bokelley bokelley deleted the bokelley/v3-1-0-followups-round-2 branch May 18, 2026 00:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant