Skip to content

RFC: define structured negotiation requests for refine_proposals #6450

Description

@bokelley

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:

  1. Rename the free-text concept from instructions to request or revision_request so the language does not imply mandatory compliance.
  2. 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.
  3. Retain a free-text field for the long tail rather than attempting to model negotiation as JSON Patch.
  4. 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

  1. Should the top-level field be request, revision_request, or another noun?
  2. What is the minimum useful typed vocabulary without recreating the entire proposal schema?
  3. Should constraints and preferences use stable IDs so results can report which ones were applied or unsatisfied?
  4. How should sellers distinguish “commercially declined,” “unsupported request type,” and “could not interpret free text”?
  5. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    claude-triagedIssue has been triaged by the Claude Code triage routine. Remove to re-triage.needs-wg-reviewBlocked on a working-group decision — surface in WG meeting agendasrfcProtocol change — auto-adds to roadmap boardspec / protocol

    Type

    No type

    Projects

    Status
    Shipped

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions