Repository navigation
Description
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.
- The buyer asks for slots in
refine_proposals. Bring backinstallment_changesonproposal-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), withinstallment_refacore/canonical-installment-ref.json. It's a request, not a term. - 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 ascreator_juniper_vale__2026-12-03. Under today's rule, buying that product buys its complete installment set, which is the selection.terms_digestbinds theproduct_idas it always has, and every 3.x buyer reads the purchase the way it already does. - What the seller can't satisfy, it says so. Bring back
unsatisfied_installment_changeson therefine_proposalsresult row, which is open, with the reason per entry. - A capability gates it. A new experimental feature id, for example
media_buy.installment_refinement, so a buyer sendsinstallment_changesonly to sellers that list it. I'd avoid reusingmedia_buy.installment_selection, because that id meant the signed field.
Rules the seller must follow
- A derived product's installment set never changes once the product is offered. A different set is a different
product_id. This is the one thing the digest doesn't bind in 3.x, so it needs to be normative. - The buyer checks the answer. Before finalizing, a buyer compares the chosen set with the returned product's
installments[]and rejects a mismatch. Committed proposals can also read back the slots a hold covers inholds[](feat(media-buy): experimental per-installment hold readback (holds) #8257). - Product membership is checked before references resolve, as feat(media-buy): add installments to the canonical product and let a proposal buy named slots #8246 required, so an unauthorized caller never makes the seller resolve a reference.
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
- 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.
- 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_changesonly 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.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsShipped
Activity
docs(reference): add the rc.0 installment experiments, with dependenc…
bokelley commentedon Nov 13, 2026
Implementation for the 3.3 RC: #8974.
installment_changesonrefine_proposalsandunsatisfied_installment_changes(with areasonper entry) on its results, under the new experimental feature idmedia_buy.installment_refinement. The seller answers with a product whoseinstallments[]is the selected set. Nothing goes intocommercial_terms. The three seller and buyer rules are normative in the schemas,refine_proposals.mdxandcollections-and-installments.mdx. Training-agent support is not included.docs(reference): describe #8974, installment refinement, in the rc.0 …
bokelley commentedon Nov 13, 2026
Proposed for 3.3 rc.0 (Mon Nov 16) as an experimental, capability-gated feature. Implementation: #8974. Buyers send
installment_changesonly to sellers that listmedia_buy.installment_refinement. Nothing is added tocommercial_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
docs(reference): add the rc.0 installment experiments, with dependenc…
docs(reference): describe #8974, installment refinement, in the rc.0 …
feat(media-buy): choose installments through refine_proposals without…
feat(media-buy): choose installments through refine_proposals without…
docs(collections): tie installment_refs to chosen installments (#8968)
feat(schema): assign a creative to specific installments of a package…
bokelley commentedon Nov 13, 2026
Implemented in #8974, merged 13 November and included in
v3.3.0-beta.6:installment_changesonrefine_proposals, experimental undermedia_buy.installment_refinement. The signedpurchases[].installments[]stays planned for 4.0 (installment_selection_required_in_4_0).