Repository navigation
Description
What kind of change?
Change a normative requirement (MUST / SHOULD / MAY)
Which section?
2.2 — Catalog references
Current text
§ 2.2: "When a proposal reaches status `agreed`, every `catalog_ref` MUST be replaced by its resolved value in the stored record, so the committed artifact is self-contained and immutable."
§ 3.1 as drafted in #22 carries no agreed-state rule for `selected[]`.Proposed text
Add after the § 2.2 resolution sentence:
"When a line item reaches status `agreed`:
(a) Each `selectable` field's `selected[]` is part of the committed artifact and is frozen.
(b) selected[] MUST satisfy the same § 2.2 self-containment guarantee as a resolved `catalog_ref` value.
(c) The frozen record MUST remain immutable and MUST be sufficient to derive pricing[].agreed_rate (per #30) without a round trip.
(d) Where an option in `available[]` is given as a `catalog_ref`, the `selected[]` entry MUST carry the version-pinned reference, and the frozen record preserves the version in effect when the selection was made.
(e) Where `selected[]` is absent, the `included[]` default composition is the frozen composition and MUST be recorded as such."Why
#22 gives the buyer's selection a key; #30 gives agreed_rate a derivation. Neither states what the committed artifact contains. The seller's half of composition self-contains at agreement — § 2.2 resolves every catalog_ref so the stored record depends on no live catalog. The buyer's half currently has no stated fate: nothing says selected[] survives into the stored record, is immutable once agreed, or pins the option version in effect.
Line items have a status independent of the proposal (§ 5.1); the rule therefore keys off line-item status, as § 5.6.1 already does for commitment — "Populated during composition. Frozen when status becomes agreed." This filing extends that precedent from the buyer's commercial commitment to the buyer's composition.
Without the freeze, four things break after agreement: a disputed invoice cannot be decomposed into base plus deltas from the record (#30 writes the formula; its inputs must be in the artifact); activation_route is operationally, not just commercially, significant — publisher_side, clean_room and id_partner are different executions, and a price does not encode the chosen route; addressable_scale and availability are recomputed against the selection (§ 3.3) but the selection they were computed against is not preserved; and a catalog that versions forward after agreement leaves the stored record's meaning dependent on live state — the exact hazard § 2.2's version pinning exists to prevent.
This also answers open question 4 of #91: how selected[] should name an option given only as a catalog_ref. Answer: by its version-pinned reference, with the version preserved in the frozen record.
#32 (VJAlkimi, Oct 8) — format validation at submission. Already consumes this concept, quoting "the line item's resolved formats selection (selected[] when present, otherwise included[])" verbatim. It validates against that resolution but never defines the field or freezes its value. This change does both.
#14 (fgranata, Sep 28) — geo becomes selectable. Accepted, with Sirajmx preparing a PR covering §5.6 and §3. The selectable surface keeps expanding — properties, audiences, now geo, and formats per #32 — and every expansion widens the composition gap this change closes.
The queue is converging on this concept; this is the change that defines it and its freeze semantics. That's a stronger position than being first — the concept already has consumers in the queue, and none of them define it or freeze it. Filing before the §3 PR solidifies puts the definition ahead of its consumers instead of chasing them.
Knock-on effects
- Depends on [Change] § 3 — Name the key the buyer writes its selection to:
selected[]on selectable fields,valueon settable fields #22 (or equivalent) landing, as [Change] § 5.6 — Give the buyer's counter a field (requested_rate), state howagreed_rateis derived, and say who can readfloorandseller_rate#30 does; not implementable alone. - [Change] § 5.3 — Say whether selected audiences combine as AND or OR, and how buyer segments and exclusions combine with them #91: open question 4 answered above; the
combineoperator freezes alongsideselected[]under the same rule. - [Change] § 4.1 — Define record_digest and assent[]; defer signer identity to the AAMP profile #63 (binding record): complementary, not overlapping —
record_digestbinds both assents over the composed object at signing; this rule governs what the stored record contains and its immutability after agreement. A digest over a mutable record still describes a mutable record. - [Change] § 5.4 — Pin each format's spec to a version and keep it in the agreed record #87 (format registry versions in the agreed record) and [Comment] § 5.10 — Require named external_references at agreed for agent proposal and deal ids #124 (named external_references at agreed): companion rules, same principle — the committed artifact is self-contained evidence. [Change] § 5.3 — Machine-readable attestations for buyer_supplied data provenance and diligence #116 (diligence_ref) extends the principle to the buyer's authority over its inputs.
- § 6 examples: once [Change] § 3 — Name the key the buyer writes its selection to:
selected[]on selectable fields,valueon settable fields #22 lands, at least one example should show a frozenselected[]in an agreed record. - No-inheritance rule (§ 2): unaffected —
selected[]is per-field, per-line-item.
Would this break an implementation already built to this draft?
No — additive or editorial
Alternatives you considered and rejected
-
Leave the freeze to [Change] § 4.1 — Define record_digest and assent[]; defer signer identity to the AAMP profile #63's
record_digest. A digest binds assent to content at signing; it does not state what the stored record contains, that selections are immutable after agreement, or how catalog-versioned options pin. The mechanisms compose; they are not substitutes. -
Rely on
negotiation_history[]. An append-only event log of field names is a process record, not a state record; reconstructing the agreed composition by replay is the burden the object model exists to absorb. -
Infer the composition from
agreed_rate. Distinct compositions can yield the same rate, zero-delta selections are price-invisible, and activation routing cannot be inferred from price at all.
You are commenting as
Individual, no organisational position
Before you submit
- I have read CONTRIBUTING.md and agree my contribution may be published under this repository's licence.
- This contains no confidential or commercially sensitive information.
Activity
KonstantinMirin commentedon Nov 12, 2026
Thanks, @peterduhon. Our PRs already cover (a), (b), (c), and (e), and (d) doesn't arise:
selected[]included (§ 4.1.1). With noselected[],included[]is in that record as published. Each party keeps it, and a later version doesn't touch it (§ 4.1.2).pricing[].agreed_rateis computed fromlist_rateand the deltas of the options in effect (§ 5.6, § 3, § 5.5, § 5.6 — Buyer writes: the selection, the settable value, and the agreed rate (#22, #30, #58) #141, § 5.6, § 5.6.5 to § 5.6.7 — Pricing: cost methods, currency, cancellation, and exclusivity (#94, #98) #146), and all of those inputs are in the record.catalog_ref: options are inline. A document the record depends on is aDocumentRef, pinned by its digest (§ 2.1, § 2.2, § 2.6, § 3 — Shared types and authoring rules (#121) #137).On your first alternative: the freeze isn't left to the digest. In #140,
agreedis terminal, and everyselectablevalue of the line item MUST remain as in the versionassent[]names (§ 4.1.2).Analyzed and generated with the help of Claude, fully reviewed by me.