Summary
Define the buyer-to-seller negotiation contract for refine_proposals. The compact lifecycle introduced by #6115 currently accepts free-text instructions, but does not distinguish a desired outcome, a hard constraint, a preference, or a request for alternative proposals. This leaves common asks such as “this is too expensive,” “keep the outcome but reduce the budget,” and “give me three meaningfully different options” without interoperable semantics.
This is the protocol gap underneath part of #6287. Competence advertisement can help a buyer predict whether free text will be understood, and proposal-level negotiation scope can say which terms a seller is willing to reconsider, but neither defines how a buyer requests a revision.
Problem
instructions implies command semantics: the seller is being told what it must do. Proposal negotiation is different. A buyer may express:
- constraints that a successful revision must satisfy, such as a maximum total budget;
- preferences the seller should optimize for when trade-offs are necessary;
- requested changes, such as adding or removing products;
- requested alternatives, including how many options and which dimensions should vary; and
- open-ended context that cannot yet be expressed in typed fields.
A single free-text field can carry all of these, but clients cannot reliably construct it, sellers cannot reliably validate it, and SDKs cannot distinguish a rejected commercial request from an unsupported or misunderstood instruction.
Proposed direction
Use a hybrid, outcome-oriented request model:
- Rename the free-text concept from
instructions to request or revision_request so the language does not imply mandatory compliance.
- Define a small typed control plane for the highest-value negotiation intents:
- budget and commercial constraints;
- product inclusion, exclusion, and substitution;
- desired number and diversity of alternatives;
- preferences and acceptable trade-offs.
- Retain a free-text field for the long tail rather than attempting to model negotiation as JSON Patch.
- Require results to distinguish fully applied, partially applied, commercially declined, and unsupported/uninterpreted requests, including which structured constraints were not satisfied.
Illustrative only:
{
"proposal_id": "prop_123",
"action": "revise",
"revision_request": {
"constraints": {
"max_total_budget": {
"amount": 50000,
"currency": "USD"
}
},
"alternatives": {
"count": 3,
"vary": ["product_mix", "budget"]
},
"preferences": ["prioritize_reach"],
"notes": "Premium video can be removed if necessary."
}
}
The final schema should express desired outcomes and boundaries, not provide a field-by-field mutation language over the proposal object.
Relationship to adjacent work
Design principles
- Proposal snapshots remain immutable; revision creates a successor proposal.
- A draft proposal is not implicitly negotiable in every dimension.
- A committed proposal has firm held terms, but may still be the source of a successor amendment or cancellation proposal.
- Structured requests must be usable by deterministic clients and SDKs without an LLM.
- Free text remains available for expressive negotiation that the typed surface does not cover.
Open questions
- Should the top-level field be
request, revision_request, or another noun?
- What is the minimum useful typed vocabulary without recreating the entire proposal schema?
- Should constraints and preferences use stable IDs so results can report which ones were applied or unsatisfied?
- How should sellers distinguish “commercially declined,” “unsupported request type,” and “could not interpret free text”?
- Should sellers advertise supported typed refinement dimensions through capabilities, leaving “competence” only for conversational interpretation?
Sequencing
Treat this as a separate RFC. Once the shape is agreed, implement it in a PR stacked on #6115 (or rebased onto main after #6115 lands), rather than adding more scope to #6115.
Summary
Define the buyer-to-seller negotiation contract for
refine_proposals. The compact lifecycle introduced by #6115 currently accepts free-textinstructions, but does not distinguish a desired outcome, a hard constraint, a preference, or a request for alternative proposals. This leaves common asks such as “this is too expensive,” “keep the outcome but reduce the budget,” and “give me three meaningfully different options” without interoperable semantics.This is the protocol gap underneath part of #6287. Competence advertisement can help a buyer predict whether free text will be understood, and proposal-level negotiation scope can say which terms a seller is willing to reconsider, but neither defines how a buyer requests a revision.
Problem
instructionsimplies command semantics: the seller is being told what it must do. Proposal negotiation is different. A buyer may express:A single free-text field can carry all of these, but clients cannot reliably construct it, sellers cannot reliably validate it, and SDKs cannot distinguish a rejected commercial request from an unsupported or misunderstood instruction.
Proposed direction
Use a hybrid, outcome-oriented request model:
instructionstorequestorrevision_requestso the language does not imply mandatory compliance.Illustrative only:
{ "proposal_id": "prop_123", "action": "revise", "revision_request": { "constraints": { "max_total_budget": { "amount": 50000, "currency": "USD" } }, "alternatives": { "count": 3, "vary": ["product_mix", "budget"] }, "preferences": ["prioritize_reach"], "notes": "Premium video can be removed if necessary." } }The final schema should express desired outcomes and boundaries, not provide a field-by-field mutation language over the proposal object.
Relationship to adjacent work
refine_proposalsand the currentinstructionsfield. The design and implementation of this RFC should be based on that work, but should not expand or delay feat(media-buy): add compact AdCP 3.2 lifecycle #6115 itself.negotiable_terms,revision_scope, or similar field would say what the seller is willing to reconsider for a particular proposal. This RFC defines how the buyer asks for that reconsideration.Design principles
Open questions
request,revision_request, or another noun?Sequencing
Treat this as a separate RFC. Once the shape is agreed, implement it in a PR stacked on #6115 (or rebased onto
mainafter #6115 lands), rather than adding more scope to #6115.