spec(enums): extract audience-status enum, formalize lifecycle transitions#2836
Merged
spec(enums): extract audience-status enum, formalize lifecycle transitions#2836
Conversation
…tions Extract the inline status enum on sync_audiences_response.audiences[].status into /schemas/enums/audience-status.json, matching the named-enum pattern used by media-buy-status, creative-status, catalog-item-status, etc. Values unchanged (processing | ready | too_small). Descriptions on the new enum file document the existing transitions in prose: processing → ready | too_small on matching completion; ready ↔ processing and too_small → processing on re-sync; ready ↔ too_small as member counts cross the platform minimum; delete/fail actions omit status. Motivation: enables audience-sync to be wired into the bundled status.monotonic cross-step assertion in a follow-up. Highest-volume mutating track outside sales without a formal lifecycle enum today (surfaced during expert review on adcp#2829). Adding the audience transition graph to @adcp/client's default-invariants is a separate adcp-client PR once this lands; wiring audience-sync/index.yaml with invariants: [status.monotonic] is a follow-up adcp PR after that SDK release. No wire change — sync_audiences responses valid before are valid after. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code review:
- Register the new audience-status enum in static/schemas/source/index.json
under definitions.enums.schemas, matching every peer (media-buy-status,
creative-status, etc.). Without it the enum is invisible to the schema
registry and downstream importers can't discover it through the index.
- Hedge the lifecycle transitions from declarative ("Transitions to...")
to permissive ("MAY transition...") on ready → processing and
ready → too_small. Matches the creative-status.json prose precedent —
the spec doesn't establish these as mandatory transitions, so asserting
them would be over-claiming.
Protocol review:
- Add normative MUST-emit-too_small sentence to the enum description on
too_small and to the Audience Status section of sync_audiences.mdx:
sellers MUST emit 'too_small' whenever matched_count < minimum_size
rather than 'ready' with a low count, so buyers have a programmatic
signal that targeting will fail. Without this, status.monotonic passes
for sellers whose real behavior is broken.
- Acknowledge clean-room / consent-review queues (LiveRamp Safe Haven and
similar) under 'processing' in the enum description — today they're
semantically correct under 'processing', worth one line so operators
aren't surprised.
Separately filed as follow-up, not this PR: seller-initiated archival /
suspension not modeled (adcp#2838).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3 tasks
4 tasks
bokelley
added a commit
that referenced
this pull request
Apr 22, 2026
… into item 11 Two schema-touch commits from the training-agent sprint that are protocol-visible: - #2839 (2ee6ac7): envelope-level `replayed` flag now accepted on 15 mutating response schemas (property-list, collection-list, governance). Previously replay responses on these tools failed schema validation. - #2836 (8ed0d4c): formal `audience-status` enum with explicit lifecycle transitions, paralleling other lifecycle-bearing resource types. Both roll into item 11 (Error Codes and Schema Consistency). No breaking-changes-table additions — the `replayed` fix is permissive, the enum formalization just elevates an implicit contract. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bokelley
added a commit
that referenced
this pull request
Apr 22, 2026
…A banners (#2302) * docs: 3.0 release notes, migration guide, specialism threading, and GA banners (#2177) Closes #2177 and #2290. Comprehensive documentation update for AdCP 3.0 GA. **Release documentation:** - Add 3.0.0 CHANGELOG entry covering every change since rc.3 - Add rc.3 → 3.0 prerelease upgrade guide with breaking changes table, before/after JSON examples, and schema file references - Expand whats-new rc.3 → 3.0 highlights with Specialisms + Compliance as a headline 3.0 pillar - Exit changeset prerelease mode so next release is stable 3.0.0 - Remove stale "use 2.5 for production" banner from intro; drop misleading "(recommended for production)" from v2.5.0 historical schema-versioning note **Specialisms + storyboards threaded through training:** - Add "Specialisms you can validate" tables to all 5 specialist modules - Add "Specialisms you can claim" to publisher and platform tracks; "Validating across sellers" to buyer track - Add Domain/Specialism/Storyboard glossary + Compliance claims section to foundations A2 module - Map skills to specialisms in build-an-agent; note brand-rights has no skill yet - Add "What changed in 3.0" callout to Compliance Catalog covering rename/merge/promotion - Thread specialisms mention through intro and quickstart **GA launch banners (#2290):** - Add Mintlify banner to docs.json: "AdCP 3.0 is now GA — see what's new" - Add dismissible announcement strip to AAO homepage - Bump docs.json default version label 3.0-rc → 3.0 **Pre-commit hook fix:** - Force vitest `pool: 'threads'` in vitest.config.ts. The default forks pool hangs indefinitely under non-TTY stdin (git pre-commit hook) because server module init in imported code keeps child processes alive. Threads share the parent lifecycle and exit cleanly. Same test speed. **Other fixes:** - Remove stale "AdCP 3.0 Proposal" banner from collection_lists.mdx - Fix major_versions: [1] → [3] in get_adcp_capabilities examples - Update publisher track B3 to use governance_context + purchase_type - Trim changelog.mdx stub to match its actual role (link to GitHub) Expert-reviewed across code, protocol, DX, docs, copy, product, security, and education. All feedback applied. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(3.0): foreground trust surface story (signing, idempotency, signed governance) Weaves the post-rc.3 trust-surface work into the 3.0 narrative across CHANGELOG, release notes, whats-new, and migration guides. Previously these PRs were merged to main but not reflected in the 3.0 documentation story. CHANGELOG.md — Adds "Breaking Changes — trust surface" and "Minor Changes — trust surface" sections: Breaking: - idempotency_key required on all mutating requests (#2315) - IO approval at task layer, not MediaBuy.pending_approval (#2270, #2351) - Art 22 / Annex III as schema invariants (#2310, #2338) - inventory-lists → property-lists, collection-lists split out (#2332, #2336) - domains → protocols compliance taxonomy (#2300) Minor: - RFC 9421 request signing profile (#2323) - Signed JWS governance_context (#2316) - Universal security baseline storyboard (#2304) - Signed-requests runner harness + runner output contract (#2350, #2352) - Cross-instance state persistence required (#2363) - Security narrative + principal terminology retirement (#2381) - URL canonicalization + sf-binary pins (#2341, #2342, #2343) Plus docs/patch entries for Operating an Agent, release cadence, CHARTER.md, AI disclosure, creative lifecycle hardening, signals baseline, Scope3 → CSBS rename, and numerous training-agent/storyboard fixes. release-notes.mdx — Rewrites the 3.0.0 intro to lead with the trust surface. Adds #1 "Trust Surface" item covering idempotency, signing, signed governance, and universal security storyboard. whats-new-in-v3.mdx — New "Trust surface: idempotency, request signing, and signed governance" section at the top of New Capabilities. prerelease-upgrades.mdx — New breaking-change rows and additive bullets for trust-surface primitives. migration/index.mdx — Adds idempotency_key, request signing, signed governance_context, IO approval task-layer move, and Art 22 schema invariants. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(3.0): fold webhooks into trust surface (signed webhooks + webhook idempotency) Webhooks now a full citizen of the 3.0 trust surface — signing unified on the RFC 9421 profile (baseline-required for sellers) and every webhook payload carries a required idempotency_key. Also picks up several spec-hardening and governance-tightening PRs that landed post-merge. CHANGELOG.md — Adds to trust-surface minor changes: - Unify webhook signing on RFC 9421 profile (#2423) - Require idempotency_key on every webhook payload (#2416, #2417) - check_governance required on every spend-commit (#2403, #2419) - Experimental status mechanism + custom pricing escape hatch (#2422) Plus patch entries for: - submitted branch on create_media_buy + ai_generated_image right-use (#2425) - time semantics + activate_signal idempotency (#2407) - known-limitations/privacy-considerations/why-not FAQs + platform-agnostic lint (#2427) - scope-truthfulness pass on three audited claims (#2385, #2404) release-notes.mdx — Renames #1 item to "Trust Surface: Idempotency, Request Signing, Signed Governance, and Signed Webhooks" and promotes webhooks to a first-class bullet. Updates intro paragraph to mention webhook signing + payload idempotency. Adds 4 new rows to the breaking changes table (webhook signing, webhook idempotency_key, revocation-notification.notification_id rename, plus MediaBuy.pending_approval placement). New webhook migration bullet at the top of the rc.3 adopter list. whats-new-in-v3.mdx — Expands the trust surface section with two new paragraphs covering webhook signing under the 9421 profile and required payload idempotency across all five webhook payload schemas. prerelease-upgrades.mdx — 4 new breaking-change rows (webhook signing, webhook payload idempotency, notification_id → idempotency_key, etc.) + 8 new additive bullets covering webhook signing, webhook idempotency, check_governance on spend-commit, experimental status mechanism, submitted branch, time semantics, and the new reference pages. migration/index.mdx — Adds webhook signing and webhook idempotency rows to the v2→v3 migration checklist. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(3.0): expert-review fixes — accurate trust-surface primitives, adcp_use placement, no protocol default on TTL Addresses three rounds of expert review (product, protocol, copy) on the 3.0 release-docs PR. **Accuracy fixes (protocol expert)**: - idempotency_key TTL: "default 24h" was wrong — schema has no default, 24h is only recommended. Clients MUST NOT assume one. Fixed in CHANGELOG, release-notes, whats-new, prerelease-upgrades. - adcp_use placement: webhook-signing JWK carries adcp_use:"webhook-signing" on the JWK inside the JWKS document at jwks_uri — NOT as a field on the brand.json agents[] entry. Clarified in all four files. - kid uniqueness: kid values MUST be unique across adcp_use purposes within a JWKS. Added to whats-new and prerelease-upgrades. - check_governance qualifier: restored "when a governance agent is configured on the plan" — was previously unconditional MUST. Added PERMISSION_DENIED as the rejection code. - UUID v4: spec allows ^[A-Za-z0-9_.:-]{16,255}$; UUID v4 is an AdCP Verified requirement, not schema-enforced. Clarified across docs. - Legacy HMAC opt-in: named the actual field (push_notification_config. authentication.credentials) where 3.x buyers opt into HMAC fallback. - 4.0 removal scope: the entire `authentication` object is removed in 4.0, not just HMAC. - webhook_signature_* reworded to "typed reason codes defined in the Security guide" — they are not enum values in error-code.json. **Narrative fixes (product + copy)**: - Primitive count reconciled: release-notes headline said 4, list had 5+1, whats-new said 3. Now consistently 4, grouped by symmetry (requests: idempotency + signing; webhooks: signing + idempotency; governance JWS as capstone). Universal security storyboard moved to item #2 (specialisms/storyboards) where it belongs as verification, not a primitive. - Opener paragraph tightened. "AdCP 3.0 makes agent-to-agent ad buying cryptographically verifiable and retry-safe." leads — the "safe for real money" overreach is softened throughout. - Connective tissue added: "Trust primitives define the bar; storyboards test it; AdCP Verified certifies it." in item #2. - Item #5 (IO approval) merged into item #12 (media buy lifecycle) — they described the same change. Numbered items now 1-14 clean. - Release notes #14 consolidated brand-schema + operating-an-agent + cadence + experimental-status + known-limitations into one "Operating an Agent, Release Cadence, CHARTER" item; brand-schema extensions pointer to CHANGELOG. - Long 14/15-step checklists deduplicated — release-notes and whats-new now link to the Security guide rather than restating them. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(3.0): remove preview specialisms, fill brand baseline, thread trust surface - Remove sales-streaming-tv, sales-exchange, sales-retail-media, and measurement-verification from the 3.0 specialism enum and catalog. They were causing confusion about what's stable at GA. Tracking reintroduction with authoritative storyboards in 3.1: #2511. - Fill the brand protocol baseline storyboard (identity-only); rights lifecycle remains in the experimental brand-rights specialism. - Rewrite quickstart step 3 to teach idempotency_key + replay semantics and step 4 to replace HMAC-SHA256 webhooks with the RFC 9421 webhook profile (JWKS-anchored, typed webhook_signature_* reason codes). - Add a trust-surface callout to the intro walkthrough so Alex's team encounters signing, idempotency replay, and signed governance JWS together at the media-buy execution moment. - Clean up cross-references in compliance-catalog, specialist learning modules (governance, media-buy), platform track, migration guide, and what's-new page. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(3.0): apply external rc.3 review fixes — versioning clarity, SI experimental flags - versioning: empty 3.1/3.2 Notes column removed; table now points at GitHub milestones for current candidate scope (no fixed commitments). - versioning: retire "architecture committee led by Brian O'Kelley" phrasing; cross-cutting decisions happen in working-group forums and public GitHub issues. Brian's role remains named in FAQ and CHARTER. - whats-new: flag Sponsored Intelligence as (experimental) in the protocol-scope comparison rows and implementer checklist, matching treatment already present on the dedicated SI section, FAQ, and governance overview. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(3.0): defensibility review P0 fixes + cutover checklist (#2538) - known-limitations:47 tense fix. Art 22 / Annex III schema invariant shipped via #2310 on 2026-04-18. - release-notes trust-framing. RFC 9421 request signing is optional in 3.0 (required only for AdCP Verified). Reframed as "retry-safe and auditable, with optional end-to-end request signing." - whats-new Verified self-attestation note. Agents publish their own runner-output.json; AAO does not audit or gate issuance. - policy-registry CSBS provenance. Formal IP donation instrument is tracked in #2314 (Evergreen, legal-gated). CSBS ships under AAO custodianship until signed assignment is on file. Launch-day cutover tracked in #2538. * docs(3.0): defensibility review P1 fixes * docs(governance): vendor Bylaws + Membership Agreement into repo (closes #2440) * docs(governance): replace HTML-comment mirror headers with MDX-safe blockquotes * docs(governance): absolute GitHub URL for governance README pointers (Mintlify broken-link fix) * chore(husky): pin mintlify to 4.2.500 in pre-push (useState crash in 4.2.515+) * docs(3.0): flip to GA — FAQ maturity, AAMP comparison, industry landscape (closes #2538 docs) * docs(3.0): Verified program launches with 3.1 — set expectations now * fix(ci): restore multi-platform optional deps in lockfile + axios types Regenerating the lockfile during the main-merge resolution was done on macOS-arm64, which only recorded darwin-arm64 entries for platform- specific optional deps (@rolldown/binding-*, @img/sharp-*). Linux CI then failed with 'Cannot find module @rolldown/binding-linux-x64-gnu' (TypeScript Build) and 'Could not load the sharp module using the linux-x64 runtime' (broken-links). Regenerated the lockfile with npm install --os=linux --cpu=x64 after nuking node_modules, which populated all platform optional deps (darwin/linux/win32/android/freebsd/wasm bindings for rolldown; full sharp platform matrix including the nested favicons/node_modules/sharp copy). Reinstalling locally after on macOS works fine — npm picks up only the darwin-arm64 bindings at runtime. Also fixes a latent typecheck error in server/src/adagents-manager.ts: axios 1.15.2 narrowed AxiosHeaders to string | number | true | string[] | AxiosHeaders | undefined, breaking the .includes() call on response.headers['content-type']. Wrap in String() to coerce safely. The lockfile regeneration bumped axios from an older 1.13.x resolve to 1.15.2 which surfaced this (existing bug, would have hit anyone regenerating the lockfile on main). * fix(ci): drop tests for two SDK-owned compliance assertions server/tests/unit/compliance-assertions.test.ts still imported spec from context-no-secret-echo.ts and idempotency-conflict-no-payload-leak.ts, both of which were deleted in the 5.8 @adcp/client upgrade (the SDK now ships both as built-in default invariants and owns the tests). Removed the two describe blocks and their imports. Kept the governance.denial_blocks_mutation tests — that assertion is still repo-local. Missed locally because npm run test:unit only scans tests/, not server/tests/ — CI catches both via test:server-unit. * docs(3.0): add item 17 (schema presence tightenings) + fold in x-annotations Two additions to the 3.0.0 release notes for work that landed on main over the last 30h but wasn't yet in our section: - Item 17 covers #2612: check-governance-response now enforces conditions/findings/expires_at presence via if/then, and sync-catalogs-response requires item_count on created/updated/ unchanged actions. Conformant agents unchanged; non-conformant ones now fail at response_schema validation instead of downstream field_present checks. - Brand schema extensions summary paragraph now also names the three non-normative x- annotations that shipped over the last 48h: x-entity (#2660 phases 1-4 complete), x-mutates-state (#2675), and the governance_policy registry/inline split (#2685). All x-* annotations — agents don't validate them; they're tooling hints for the storyboard context-entity lint. * docs(3.0): fold envelope-replayed schema fix and audience-status enum into item 11 Two schema-touch commits from the training-agent sprint that are protocol-visible: - #2839 (2ee6ac7): envelope-level `replayed` flag now accepted on 15 mutating response schemas (property-list, collection-list, governance). Previously replay responses on these tools failed schema validation. - #2836 (8ed0d4c): formal `audience-status` enum with explicit lifecycle transitions, paralleling other lifecycle-bearing resource types. Both roll into item 11 (Error Codes and Schema Consistency). No breaking-changes-table additions — the `replayed` fix is permissive, the enum formalization just elevates an implicit contract. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
processing | ready | too_smallstatus enum onsync_audiences_response.audiences[].statusintostatic/schemas/source/enums/audience-status.json, matching the named-enum pattern used by every other lifecycle-bearing resource (media-buy-status,creative-status,catalog-item-status,proposal-status,si-session-status,account-status,collection-status,creative-approval-status).enumDescriptionentries:processing → ready | too_smallon matching completionready ↔ processingandtoo_small → processingon re-sync (new members → re-match)ready ↔ too_smallas member counts cross the platform minimumaction: 'deleted' | 'failed'actions omitstatusentirely (terminal-like from the envelope perspective; the assertion extractor only records observations whenstatusis present)sync-audiences-response.jsonnow\$refs the new enum instead of inlining.Why
Follow-up from expert review on adcp#2829.
status.monotonicgates status transitions across storyboard steps against the spec-published lifecycle graph.audience-syncis the highest-volume mutating track outside sales but was skipped in #2829's wiring because it had no formal lifecycle enum in the spec. This PR closes that gap.Follow-ups (not this PR)
default-invariants.ts'sAUDIENCE_TRANSITIONSconstant + task extractor forsync_audiences/list_audiences. Separate PR once this lands and publishes.static/compliance/source/specialisms/audience-sync/index.yamlwithinvariants: [status.monotonic]. Follow-up PR after the adcp-client release lands.Test plan
npm run test:schemas— 7/7 passnpm run test:json-schema— 249/249 passnpm run test:examples— 34/34 passsync_audiencesresponses that were valid before are valid after🤖 Generated with Claude Code