Skip to content

epic: make proposal negotiation easy to implement, teach, and verify #6556

Description

@bokelley

Goal

Make structured proposal negotiation straightforward to implement, teach, and verify across the official AdCP SDKs and reference tooling after #6450 / #6547.

The protocol now distinguishes mechanically verifiable dimensions (total_budget, product_changes, alternatives, and criteria) from the free-text ask, with deterministic partial/unable outcomes, immutable proposal lineage, and atomic finalization. Implementors still need reusable SDK workflows, a reference seller that exercises the complete surface, implementation guidance, and conformance scenarios.

Workstreams

Shared design requirements

  • Typed helpers MUST preserve the protocol distinction between task-level errors and per-proposal revised, partial, unable, and finalized outcomes.
  • SDKs MUST validate capabilities and cardinality before mutation, including the protocol maxima of 10 alternatives and 25 refinements.
  • SDKs SHOULD provide verification and orchestration primitives, but MUST NOT embed commercial policy or silently reinterpret a seller counteroffer.
  • Buyer APIs MUST handle capability discovery, exact idempotent retries, changed-request retry keys, response verification, finalization, and expiry-aware acceptance.
  • Seller APIs MUST support capability declaration, preflight validation, immutable successor creation, response validation, and atomic finalization hooks.
  • The training agent MUST consume the TypeScript SDK primitives rather than maintaining a second incompatible implementation.
  • Docs and storyboards MUST use the same scenarios and expected outcomes.

Definition of done

  • All official SDK repositories expose documented, tested proposal-negotiation support for their supported client/server surfaces.
  • The public training seller offers both ask-only and deterministic typed-negotiation profiles.
  • An implementor can follow one guide from capabilities through negotiation, finalization, acceptance, amendment, and cancellation.
  • The compliance suite covers success, counteroffer, rejection, limits, mutation safety, idempotency, and atomicity.
  • A buyer agent can run the documented scenario against the training seller and pass the same assertions used by the storyboards.

Dependencies

Contract additions from the pre-merge red team (#6547, efe48f522e)

The wire contract grew before merge; every child ticket should target this surface, not the original four-dimension draft:

  • Typed hard constraints now include cpm (fixed-rate ceiling), impressions (volume floor), and flight (window bounds) alongside total_budget — all verified against commercial_terms.
  • Capability dimension product_selection was renamed product_changes; dimensions now match request fields exactly.
  • unsatisfied_constraints carries open string keys (no closed enum) so future dimensions are additive.
  • reason_code precedence: constraint_unsatisfiable wins over every other code; typed failures never use commercially_declined (ask-level refusals only). New codes hold_unavailable and batch_aborted cover finalize failures in the atomic batch; double-finalize of a held draft is task-level INVALID_STATE.
  • Undeclared-dimension rejection is a MUST (task-level, pre-mutation) with a registered error-details/unsupported-refinement-dimension.json details shape.
  • Every refinement successor requires parent_proposal_id equal to its source proposal — negotiation lineage is reconstructible from proposals alone.
  • terms_digest is buyer-recomputable (RFC 8785 JCS + sha256/base64url); alternative distinctness is defined on commercial_terms, not digest strings.
  • New normative text: partial drafts satisfy every constraint absent from unsatisfied_constraints; only commercial_terms is contractual; ask is untrusted input to fence from pricing authority; deterministic constraint responses form a price oracle sellers should rate-limit; legacy budget_range (soft) vs compact total_budget (hard) share a shape with inverted semantics.

Metadata

Metadata

Assignees

No one assigned

    Labels

    claude-triagedIssue has been triaged by the Claude Code triage routine. Remove to re-triage.epicMajor deliverable — auto-adds to roadmap boardmedia-buyIssue concerns the media-buy protocol domain

    Type

    No type

    Projects

    Status
    No status

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions