From 4cdad141b7414bd081edcbe76e0c15214952f7bb Mon Sep 17 00:00:00 2001 From: Brian O'Kelley Date: Wed, 3 Jun 2026 17:01:28 -0400 Subject: [PATCH] docs(creative): align get_creative_features with its already-Final lifecycle stage + close CREATIVE_INACCESSIBLE phantom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit get_creative_features is already at the Final lifecycle stage per docs/reference/specification-lifecycle.mdx (no x-status marker + shipped in 3.0 GA + absent from experimental_features => Final). It is a Required creative-governance task with a complete request/response/result schema surface and a get_adcp_capabilities capability. The task carried a stale "AdCP 3.0 Proposal — under development" prose banner that contradicted that Final state. - Remove the proposal banner from get_creative_features.mdx and the creative-governance section landing page index.mdx (the section's only banner-marked page; provenance-verification carries no proposal banner). - Add CREATIVE_INACCESSIBLE to the error-code enum (enumDescriptions + enumMetadata, recovery=correctable) + drift disposition (held-for-next-minor/3.1). The task's error example documented this code but it was absent from the enum — a documented surface must not emit a phantom code (#3456 enum-membership criterion). Distinct from CREATIVE_NOT_FOUND / CREATIVE_REJECTED / GOVERNANCE_UNAVAILABLE. No schema field changes, no behavior change, no lifecycle transition. Unblocks the 3.1 creative-feature-oracle gate/rank pipeline (#5311 / #5305) which uses get_creative_features as the gate's feature source. Refs #5311, #5305, #3456. Co-Authored-By: Claude Opus 4.8 (1M context) --- .changeset/finalize-get-creative-features.md | 18 ++++++++++++++++++ .../creative/get_creative_features.mdx | 4 ---- docs/governance/creative/index.mdx | 4 ---- scripts/error-code-drift-dispositions.json | 5 +++++ static/schemas/source/enums/error-code.json | 6 ++++++ 5 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 .changeset/finalize-get-creative-features.md diff --git a/.changeset/finalize-get-creative-features.md b/.changeset/finalize-get-creative-features.md new file mode 100644 index 0000000000..918b770608 --- /dev/null +++ b/.changeset/finalize-get-creative-features.md @@ -0,0 +1,18 @@ +--- +"adcontextprotocol": minor +--- + +Align `get_creative_features` documentation with its already-Final lifecycle stage, and close a phantom error code. + +Per [specification-lifecycle](docs/reference/specification-lifecycle.mdx) (a surface with no `x-status` marker that has shipped in a GA release is at the **Final** stage), `get_creative_features` is already Final: none of its schemas (`get-creative-features-request.json`, `get-creative-features-response.json`, `creative-feature-result.json`) carry `x-status: experimental`, it shipped in 3.0 GA, and it is absent from the canonical `experimental_features` list in [experimental-status](docs/reference/experimental-status.mdx). It is listed as a **Required** creative-governance task in `docs/protocol/required-tasks.mdx`, and its capability is advertised via `get_adcp_capabilities.creative_features[]`. The task carried a stale "AdCP 3.0 Proposal — under development" prose banner that contradicted that Final state. This is not a Proposed→Final transition — the lifecycle stage is unchanged — so no decision record is required; it removes a contradictory documentation artifact. + +**Changes** + +- Removed the proposal `` banner from `docs/governance/creative/get_creative_features.mdx` and the creative-governance section landing page `docs/governance/creative/index.mdx`. The section's only banner-marked page was `get_creative_features`; `provenance-verification` carries no proposal banner. +- Added `CREATIVE_INACCESSIBLE` to the canonical error-code enum (with `enumDescriptions` and `enumMetadata`, recovery `correctable`). The `get_creative_features` error example documented this code but it was absent from the enum — a documented task surface must not emit a phantom code (#3456 enum-membership criterion). It fires when a creative governance agent cannot retrieve the submitted `creative_manifest` assets at all — distinct from `CREATIVE_NOT_FOUND` (a `creative_id` absent from the agent's library), `CREATIVE_REJECTED` (assets retrieved but failed policy), and `GOVERNANCE_UNAVAILABLE` (agent unreachable; transient). + +No schema field changes; no behavior change to the task. The `creative/specification.mdx` (v1 creative model) and `media-buy/specification.mdx` proposal banners are unrelated surfaces and unchanged. The frozen `dist/docs//` release snapshots still carry the banner by design — they refresh at the next snapshot cut, not on content PRs. + +This unblocks the 3.1 creative-feature-oracle gate/rank pipeline (#5311 / #5305), which uses `get_creative_features` as the gate's feature source. + +Refs #5311, #5305, #3456. diff --git a/docs/governance/creative/get_creative_features.mdx b/docs/governance/creative/get_creative_features.mdx index 57d287a367..4985b6b26d 100644 --- a/docs/governance/creative/get_creative_features.mdx +++ b/docs/governance/creative/get_creative_features.mdx @@ -6,10 +6,6 @@ description: "get_creative_features evaluates a creative manifest against a gove # get_creative_features - -**AdCP 3.0 Proposal** - This task is under development for AdCP 3.0. - - Evaluates a creative manifest and returns feature values from a creative governance agent. ## Use cases diff --git a/docs/governance/creative/index.mdx b/docs/governance/creative/index.mdx index d383c85db2..7fabe3863a 100644 --- a/docs/governance/creative/index.mdx +++ b/docs/governance/creative/index.mdx @@ -5,10 +5,6 @@ description: "AdCP Creative Governance provides standardized creative evaluation sidebarTitle: Overview --- - -**AdCP 3.0 Proposal** - This protocol is under development for AdCP 3.0. Feedback welcome via [GitHub Discussions](https://github.com/adcontextprotocol/adcp/discussions). - - Creative Governance standardizes how creatives are evaluated by specialized governance agents. It applies the same feature-based pattern as [Property Governance](../property/index) — agents declare features they can evaluate, accept creative manifests, and return feature values. ## Overview diff --git a/scripts/error-code-drift-dispositions.json b/scripts/error-code-drift-dispositions.json index 7bc94b7d77..fa71e78cfc 100644 --- a/scripts/error-code-drift-dispositions.json +++ b/scripts/error-code-drift-dispositions.json @@ -1,6 +1,11 @@ { "$comment": "Disposition registry for error codes that are present in the current source enum but absent from the 3.0.x maintenance branch. Read by scripts/lint-error-code-drift.cjs. Every code in the AHEAD set (main \\ 3.0.x) MUST have an entry here; codes missing from this file fail the lint. Policy: 3.0.x is wire-stable. Adding a new enum value is a wire change (a 3.0.x receiver decoding a 3.1 sender's error.code cannot match against an enum it doesn't carry, and JSON Schema enum is closed by default), so the default disposition for any new code is 'held-for-next-minor' with target_version='3.1'. 'held-for-next-major' (target_version='4.0') is for codes that should defer past 3.x \u2014 typically because the surrounding subsystem is being reworked. 'backport-pending' is reserved for prose-only or doc-comment-only changes to a code that already exists on 3.0.x; the lint rejects backport-pending entries whose code is not on 3.0.x. Valid `disposition` values: 'backport-pending', 'held-for-next-minor', 'held-for-next-major', 'unclassified'. `target_version` (required for held-*) is a 'MAJOR.MINOR' string. When a code lands on 3.0.x its entry SHOULD be removed; the lint flags stale entries.", "dispositions": { + "CREATIVE_INACCESSIBLE": { + "disposition": "held-for-next-minor", + "target_version": "3.1", + "note": "get_creative_features finalization — governance agent could not retrieve the creative_manifest assets for evaluation. Documented in get_creative_features.mdx error example but absent from the canonical enum; added to close the phantom as the task is promoted from 3.0 proposal to normative in 3.1 (#3456 enum-membership criterion). Wire change — held for 3.1." + }, "FEED_FETCH_FAILED": { "disposition": "held-for-next-minor", "target_version": "3.1", diff --git a/static/schemas/source/enums/error-code.json b/static/schemas/source/enums/error-code.json index 49f485873e..1ccddf0786 100644 --- a/static/schemas/source/enums/error-code.json +++ b/static/schemas/source/enums/error-code.json @@ -40,6 +40,7 @@ "IDEMPOTENCY_EXPIRED", "IDEMPOTENCY_IN_FLIGHT", "CREATIVE_DEADLINE_EXCEEDED", + "CREATIVE_INACCESSIBLE", "INVALID_STATE", "MEDIA_BUY_NOT_FOUND", "NOT_CANCELLABLE", @@ -127,6 +128,7 @@ "BUDGET_EXCEEDED": "Operation would exceed the allocated budget for the media buy or package. Distinct from BUDGET_EXHAUSTED (already spent) and BUDGET_TOO_LOW (below minimum). Recovery: correctable (reduce requested amount or increase budget allocation).", "BUDGET_CAP_REACHED": "build_creative stopped producing early because the next leaf would exceed the request's max_spend ceiling. Normally a SUCCESSFUL partial build (BuildCreativeVariantSuccess with budget_status: 'capped' and an advisory BUDGET_CAP_REACHED entry — every returned leaf is real and billed); returned as a terminal error only when even the first leaf would exceed the cap (no partial possible). Distinct from BUDGET_EXCEEDED (would exceed a media-buy/package allocation — a rejection) and BUDGET_EXHAUSTED (already spent). Recovery: correctable (raise max_spend, or reduce max_creatives/max_variants).", "CREATIVE_DEADLINE_EXCEEDED": "Creative change submitted after the package's creative_deadline. Distinct from CREATIVE_REJECTED (content policy failure). Recovery: correctable (check creative_deadline via get_media_buys before submitting changes, or negotiate a deadline extension with the seller).", + "CREATIVE_INACCESSIBLE": "A creative governance agent (get_creative_features) could not retrieve the submitted creative_manifest assets for evaluation — an asset URL was unreachable, returned an error, or required credentials the agent does not hold. Distinct from CREATIVE_NOT_FOUND (a creative_id absent from the agent's library, not an asset-fetch failure) and CREATIVE_REJECTED (assets retrieved but failed policy). Recovery: correctable (verify the asset URLs are reachable without agent-side credentials, then re-submit).", "CONFLICT": "Concurrent modification detected. The resource was modified by another request between read and write. Recovery: transient (re-read the resource and retry with current state).", "IDEMPOTENCY_CONFLICT": "An earlier request with the same idempotency_key was processed with a different canonical payload within the seller's replay window. Distinct from CONFLICT (concurrent write) — this indicates the client reused a key across semantically different requests. Recovery: correctable (use a fresh UUID v4 for the new request, or resend the exact original payload to get the cached response).", "IDEMPOTENCY_EXPIRED": "The idempotency_key was seen previously but its cached response has been evicted because it is past the seller's declared replay_ttl_seconds. Distinct from IDEMPOTENCY_CONFLICT (different payload within window) — this indicates the retry arrived too late for at-most-once guarantees. Recovery: correctable (perform a natural-key reconciliation — e.g., call get_media_buys for the relevant account/status scope and match returned media_buys[].context.internal_campaign_id — to determine whether the original request succeeded, then either accept that result or generate a fresh idempotency_key for a new attempt). If the buyer has any evidence the prior call succeeded (partial response received before crash, entry in the buyer's own DB, a webhook fired), the buyer MUST do the natural-key reconciliation BEFORE minting a new key — minting a new key in that situation is exactly how double-creation happens.", @@ -328,6 +330,10 @@ "recovery": "correctable", "suggestion": "check creative_deadline via get_media_buys before submitting changes, or negotiate a deadline extension with the seller" }, + "CREATIVE_INACCESSIBLE": { + "recovery": "correctable", + "suggestion": "verify the asset URLs in creative_manifest are reachable without agent-side credentials, then re-submit" + }, "INVALID_STATE": { "recovery": "correctable", "suggestion": "check current status via get_media_buys and adjust request"