Skip to content

feat(training): add deterministic typed proposal negotiation profiles #6558

Description

@bokelley

Goal

Turn the public training seller from ask-only proposal refinement into a deterministic environment where buyer-agent and seller-agent implementors can exercise the complete AdCP 3.2 negotiation lifecycle.

Parent program: #6556
Protocol implementation: #6547

Profiles

Keep the existing ask-only profile and add capability-distinct profiles such as:

  1. Typed negotiation: supports total_budget, product_changes, criteria, and alternatives, with max_alternatives: 3.
  2. Constrained seller: supports the same dimensions but has deterministic commercial floors, product conflicts, targeting effects, and fewer available alternatives.
  3. Finalization failure: exercises atomic hold creation, expiry, retry, and rollback.

Acceptance criteria

  • Consume the proposal-negotiation primitives from @adcp/sdk; do not maintain a second incompatible validator/orchestrator.
  • Use deterministic fixture policy rather than an LLM as the source of commercial truth.
  • Produce valid revised, partial, unable, and finalized outcomes with all reason codes reachable through documented scenarios.
  • Preserve immutable proposal lineage and never mutate source snapshots.
  • Apply capability and cardinality preflight to the entire request before mutation.
  • Support exact idempotent replay and reject changed payloads under a reused key.
  • Stage writes until response validation passes; finalize batches create every hold or none.
  • Expose a stable scenario/config selector usable by SDK integration tests, storyboards, and certification labs.

Required end-to-end scenario

  • Buyer discovers a three-alternative ceiling.
  • Buyer requests a USD 50,000 cap, product include/omit changes, US/Canada criteria, and three alternatives.
  • Seller returns two valid drafts with partial / alternatives_unavailable.
  • Buyer retries with two, selects one, finalizes it, and accepts before expiry.
  • Buyer later creates an amendment and a cancellation proposal without mutating the accepted source.

Tests

  • Cover all typed dimensions and reason codes.
  • Cover task-wide unsupported-dimension rejection with no sibling mutation.
  • Cover 10-alternative and 25-refinement boundaries.
  • Cover missing/wrong-currency/out-of-range budgets, duplicate digests, partial counts, missing sources, replay, expiry, and atomic finalize failure.

Dependencies

Additional scope (contract hardening in #6547, efe48f522e)

  • The typed-negotiation profile should also advertise and implement cpm, impressions, and flight (all now schema-defined and validator-checked); note the capability dimension is product_changes, not product_selection.
  • The deterministic engine must classify per the precedence rule: constraint_unsatisfiable wins over alternatives_unavailable/uninterpreted; typed failures never surface as commercially_declined.
  • Finalize paths: simulate hold_unavailable (inventory sold since drafting, hold-policy cap) and batch_aborted siblings in the atomic batch; enforce a concurrent-hold cap per buyer as the reference for the documented squatting defense; double-finalize returns INVALID_STATE (already shipped for the ask-only profile).
  • The response validator now enforces recomputed terms_digest, distinct commercial_terms across alternatives, and parent_proposal_id = source on every successor — profile outputs get this for free but must not fight it.
  • partial outputs must honor the invariant that unlisted constraints are satisfied by every returned draft.

Metadata

Metadata

Assignees

No one assigned

    Labels

    claude-triagedIssue has been triaged by the Claude Code triage routine. Remove to re-triage.enhancementNew feature or requestmedia-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