Skip to content

compliance(media-buy): add proposal negotiation storyboard matrix #6559

Description

@bokelley

Goal

Add a capability-gated proposal-negotiation storyboard matrix for AdCP 3.2 so implementors can test correctness, experiment with counteroffers, and compare their behavior with the public training seller.

Parent program: #6556
Related compact lifecycle suite: #6432
Protocol implementation: #6547

Required storyboard coverage

Capability and preflight

  • Ask-only seller accepts ask revision.
  • Explicitly unsupported typed dimension causes task-level UNSUPPORTED_FEATURE for the entire mixed batch with no mutation.
  • Advertised max_alternatives violation causes task-level VALIDATION_ERROR with no mutation.
  • Protocol boundaries: 10 alternatives accepted when the seller ceiling permits; 11 rejected; 25 refinements accepted; 26 rejected.

Typed revision outcomes

  • Budget satisfied, absent, wrong currency, below/above bounds.
  • Product include/omit satisfied and unsatisfied.
  • Structured criteria replacement with omitted criteria inherited.
  • Exact alternative count with unique terms_digest values.
  • Fewer distinct alternatives reported as partial / alternatives_unavailable.
  • Duplicate alternatives or false revised claims fail validation.
  • Commercial refusal, uninterpreted ask, unsupported dimension when capabilities are unknown, and source unavailable.
  • Ordered multi-source batch with a valid mix of revised, partial, and unable results.

Lifecycle, mutation, and retry

  • Every successful revision creates a new immutable proposal and leaves the source unchanged.
  • Exact replay returns the same outcome; changed payload under the same idempotency key conflicts.
  • Finalize creates a committed proposal with expires_at and unchanged terms/digest.
  • Multi-finalize is atomic on success and failure; no partial holds.
  • Acceptance before and after expiry.
  • Amendment and cancellation successors from an accepted proposal.

Experimentation support

  • Provide a stable training-agent test kit/profile whose deterministic responses match the storyboard fixtures.
  • Document how SDK maintainers run the matrix against local buyer/seller implementations.
  • Capture identifiers and proposal lineage so a developer can inspect every transition.
  • Include negative variants that intentionally violate one invariant and explain the expected failure.

Acceptance criteria

  • Scenarios are gated by advertised 3.2 lifecycle/capability support and do not penalize legacy or ask-only sellers for undeclared typed behavior.
  • Current /sales floors and required-clean assertions include the negotiation core.
  • Storyboard lint, fixture-resolution, contradiction, context-entity, and 3.0 compatibility checks remain green.
  • The same matrix runs against the public training seller and is consumable by official SDK integration tests.

Additional required coverage (contract hardening in #6547, efe48f522e)

New typed constraints

  • cpm, impressions, and flight each satisfied and violated; violated drafts must appear as partial/unable with constraint_unsatisfiable and the failing key echoed in unsatisfied_constraints.
  • Co-occurring failures (violated constraint + alternatives shortfall) must use constraint_unsatisfiable, with the shortfall visible only through proposals.length.

Rejection and error shapes

  • Undeclared-dimension rejection is now a MUST: task-level UNSUPPORTED_FEATURE before any mutation, with details matching error-details/unsupported-refinement-dimension.json.
  • Capability dimension name is product_changes (renamed from product_selection).

Holds

  • Failing finalize entry returns unable/hold_unavailable; otherwise-eligible siblings return unable/batch_aborted; no partial finalize batches.
  • Double-finalize of a held draft fails task-level with INVALID_STATE.

Integrity

  • Every returned proposal carries parent_proposal_id equal to source_proposal_id.
  • terms_digest recomputes from RFC 8785 JCS of commercial_terms; a tampered digest or duplicate-terms "alternatives" must fail validation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    claude-triagedIssue has been triaged by the Claude Code triage routine. Remove to re-triage.compliancecompliance-suitemedia-buyIssue concerns the media-buy protocol domain

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions