Skip to content

RFC: Choose specific installments in 3.x without opening commercial_terms #8967

Closed

Description

@bokelley

Problem

A buyer can't choose which slots it buys from a product that lists installments. In 3.3, a purchase buys the product as offered, which means every installment the product declares (collections and installments, "Buying a product that names installments"). Installment selection (#8246) was withdrawn after beta.1 in #8537, because it added purchases[].installments[] to commercial_terms, which stays closed until 4.0 (#8501).

That leaves creator, podcast and sponsorship sellers with one workaround: publish one product per slot up front. It works, but it multiplies catalogs, and the buyer still can't ask "these two posts, not that one" during negotiation. Availnet, the creator-marketplace adopter behind #8230, needs exactly that negotiation. #7777 item 2 asks for the same thing for print, broadcast and OOH.

Proposal: select on the request side, bind with an ordinary product

Nothing new goes into commercial_terms, and no signed field changes meaning.

  1. The buyer asks for slots in refine_proposals. Bring back installment_changes on proposal-refinement.json, which fix(schemas): open the 3.3 schemas that were meant to be open #8866 opened, with the shape feat(media-buy): add installments to the canonical product and let a proposal buy named slots #8246 used and v4-compatibility preserves: a list of { product_id, installment_ref, action }, unique by (product_id, installment_ref), with installment_ref a core/canonical-installment-ref.json. It's a request, not a term.
  2. The seller answers with a product that declares exactly the chosen slots. The revised draft's purchase references a product whose installments[] is the selected set. It might be a product the seller derives for this selection, such as creator_juniper_vale__2026-12-03. Under today's rule, buying that product buys its complete installment set, which is the selection. terms_digest binds the product_id as it always has, and every 3.x buyer reads the purchase the way it already does.
  3. What the seller can't satisfy, it says so. Bring back unsatisfied_installment_changes on the refine_proposals result row, which is open, with the reason per entry.
  4. A capability gates it. A new experimental feature id, for example media_buy.installment_refinement, so a buyer sends installment_changes only to sellers that list it. I'd avoid reusing media_buy.installment_selection, because that id meant the signed field.

Rules the seller must follow

Why not narrow the purchase's flight to the slot dates?

I suggested that first, and it doesn't work. The purchase would still buy the product's complete installment set, because nothing says a narrower flight drops installments outside it. Saying so now would change what a signed start_time/end_time means for a 3.2 or 3.3 buyer, which rule 3 in the #8501 disposition rules out.

What 4.0 still does

4.0 keeps the design in v4-compatibility (installment_selection_required_in_4_0): purchases[].installments[] in the signed terms, so the digest binds the slots themselves, not just the product ID. Products derived for one selection can retire then.

Questions for the working group

  1. Is a derived, per-selection product acceptable in the proposal flow, or should sellers only ever offer products from their published catalog? If the latter, the seller can still pre-publish per-slot products and the refinement request just picks between them.
  2. Can this make the 3.3 RC (Mon 16 Nov)? All of it sits on schemas that are now open, plus one new feature id. The capability gate keeps it within docs(versioning): state the rules for what changes between releases #8704: a buyer sends installment_changes only to a seller that lists the feature, so an older seller never ignores it. With no 3.4, the alternative is waiting for 4.0, which does the signed version anyway, so this is only worth doing if it makes 3.3.

Related: #8230, #8246, #8537, #8501, #7777, #8257. Adopter: Availnet (creator marketplace) through Apostra.

Activity

  1. added
    rfcProtocol change — auto-adds to roadmap board
    media-buyIssue concerns the media-buy protocol domain
    on Nov 13, 2026
  2. added this to the 3.3.0 milestone on Nov 13, 2026
  3. bokelley commented on Nov 13, 2026

    @bokelley
    ContributorAuthor

    Implementation for the 3.3 RC: #8974. installment_changes on refine_proposals and unsatisfied_installment_changes (with a reason per entry) on its results, under the new experimental feature id media_buy.installment_refinement. The seller answers with a product whose installments[] is the selected set. Nothing goes into commercial_terms. The three seller and buyer rules are normative in the schemas, refine_proposals.mdx and collections-and-installments.mdx. Training-agent support is not included.

  4. added a commit that references this issue on Nov 13, 2026
  5. bokelley commented on Nov 13, 2026

    @bokelley
    ContributorAuthor

    Proposed for 3.3 rc.0 (Mon Nov 16) as an experimental, capability-gated feature. Implementation: #8974. Buyers send installment_changes only to sellers that list media_buy.installment_refinement. Nothing is added to commercial_terms, and no signed field changes meaning, so it stays within #8704.

    Objections by Sun Nov 15. If there are none, it ships in rc.0. The RFC questions above stay open for the 4.0 design.

    🤖 Generated with Claude Code

  6. bokelley commented on Nov 13, 2026

    @bokelley
    ContributorAuthor

    Implemented in #8974, merged 13 November and included in v3.3.0-beta.6: installment_changes on refine_proposals, experimental under media_buy.installment_refinement. The signed purchases[].installments[] stays planned for 4.0 (installment_selection_required_in_4_0).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    media-buyIssue concerns the media-buy protocol domainrfcProtocol change — auto-adds to roadmap board

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions