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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .changeset/finalize-get-creative-features.md
Original file line number Diff line number Diff line change
@@ -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 `<Info>` 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/<version>/` 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.
4 changes: 0 additions & 4 deletions docs/governance/creative/get_creative_features.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ description: "get_creative_features evaluates a creative manifest against a gove

# get_creative_features

<Info>
**AdCP 3.0 Proposal** - This task is under development for AdCP 3.0.
</Info>

Evaluates a creative manifest and returns feature values from a creative governance agent.

## Use cases
Expand Down
4 changes: 0 additions & 4 deletions docs/governance/creative/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ description: "AdCP Creative Governance provides standardized creative evaluation
sidebarTitle: Overview
---

<Info>
**AdCP 3.0 Proposal** - This protocol is under development for AdCP 3.0. Feedback welcome via [GitHub Discussions](https://github.com/adcontextprotocol/adcp/discussions).
</Info>

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
Expand Down
5 changes: 5 additions & 0 deletions scripts/error-code-drift-dispositions.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
6 changes: 6 additions & 0 deletions static/schemas/source/enums/error-code.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"IDEMPOTENCY_EXPIRED",
"IDEMPOTENCY_IN_FLIGHT",
"CREATIVE_DEADLINE_EXCEEDED",
"CREATIVE_INACCESSIBLE",
"INVALID_STATE",
"MEDIA_BUY_NOT_FOUND",
"NOT_CANCELLABLE",
Expand Down Expand Up @@ -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.",
Expand Down Expand Up @@ -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"
Expand Down
Loading