diff --git a/conformance/descriptor_invariants_test.go b/conformance/descriptor_invariants_test.go index 7c66642..ad6f602 100644 --- a/conformance/descriptor_invariants_test.go +++ b/conformance/descriptor_invariants_test.go @@ -297,25 +297,17 @@ func fieldEnum(t *testing.T, md protoreflect.MessageDescriptor, field string) pr } // TestRequesterBillingRefStaysRemoved pins the billing_ref removal at the -// descriptor level: Requester carries no billing_ref field and no field 5, -// and both stay reserved. protoc enforces the reservation only while the two -// `reserved` statements exist in the source; `buf breaking` (which would flag -// deleting them) is non-blocking pre-v1, and the remark-proto guard runs only -// in the docs build. This is the blocking-CI pin: reusing the number under a -// new name, or the name under a new number, fails here. +// descriptor level: Requester carries no caller-written billing_ref field. +// Billing identity is resolved from the verified request signature and the +// account minted at Register, never from a request field — a reappearing +// billing_ref would also collide by name with the authoritative account +// handle (RegisterResponse.billing_ref). The freed field number is NOT +// pinned: pre-v1, removed numbers return to the free pool (no `reserved` +// statements until v1.0.0 is tagged). func TestRequesterBillingRefStaysRemoved(t *testing.T) { md := (&rampv1.Requester{}).ProtoReflect().Descriptor() if fd := md.Fields().ByName("billing_ref"); fd != nil { - t.Errorf("Requester regained a billing_ref field (number %d) — it was removed and its number reserved", fd.Number()) - } - if fd := md.Fields().ByNumber(5); fd != nil { - t.Errorf("Requester field number 5 reused by %q — it must stay reserved", fd.Name()) - } - if !md.ReservedRanges().Has(5) { - t.Error("Requester no longer reserves field number 5 — restore `reserved 5;`") - } - if !md.ReservedNames().Has("billing_ref") { - t.Error(`Requester no longer reserves the name billing_ref — restore 'reserved "billing_ref";'`) + t.Errorf("Requester regained a billing_ref field (number %d) — billing keys on the verified caller identity, never a request field", fd.Number()) } } diff --git a/docs/design-history.md b/docs/design-history.md index ac44036..37c0b98 100644 --- a/docs/design-history.md +++ b/docs/design-history.md @@ -145,7 +145,8 @@ records only the wire-shaping reasoning. > after the Broker cost guard moved to the authenticated agent identity, > nothing read `Requester.billing_ref`, and the caller-written > label collided by name with the authoritative account handle minted at -> `Register`. Field 5 and the name are now `reserved`. The reasoning below +> `Register`. The field was deleted outright — pre-v1, removed field numbers +> return to the free pool rather than being `reserved`. The reasoning below > still stands — it is the same separation (identity = signature, > entitlement = scopes/delegation) taken one step further: billing needs no > request field at all. diff --git a/gen/descriptor.binpb b/gen/descriptor.binpb index 989a21d..e3c9ee6 100644 Binary files a/gen/descriptor.binpb and b/gen/descriptor.binpb differ diff --git a/gen/go/ramp/v1/ramp.pb.go b/gen/go/ramp/v1/ramp.pb.go index d921674..f5ad886 100644 --- a/gen/go/ramp/v1/ramp.pb.go +++ b/gen/go/ramp/v1/ramp.pb.go @@ -9007,7 +9007,7 @@ const file_ramp_v1_ramp_proto_rawDesc = "" + "\x13_estimated_quantityB\x1a\n" + "\x18_license_duration_monthsB\a\n" + "\x05_unitB\v\n" + - "\t_metering\"\xd7\x02\n" + + "\t_metering\"\xc4\x02\n" + "\tRequester\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x16\n" + "\x06domain\x18\x02 \x01(\tR\x06domain\x124\n" + @@ -9020,7 +9020,7 @@ const file_ramp_v1_ramp_proto_rawDesc = "" + "\x03ext\x18\x0f \x01(\v2\x17.google.protobuf.StructR\x03ext\x12!\n" + "\fext_critical\x18Z \x03(\tR\vextCriticalB\a\n" + "\x05_nameB\r\n" + - "\v_delegationJ\x04\b\x05\x10\x06R\vbilling_ref\"\xe9\x04\n" + + "\v_delegation\"\xe9\x04\n" + "\n" + "Delegation\x12)\n" + "\x10principal_domain\x18\x01 \x01(\tR\x0fprincipalDomain\x12!\n" + diff --git a/proto/CHANGELOG.md b/proto/CHANGELOG.md index b8f9e12..31dd870 100644 --- a/proto/CHANGELOG.md +++ b/proto/CHANGELOG.md @@ -50,9 +50,10 @@ two flags (`SKIP_SSRF`, `ALLOW_INSECURE`). See `docs/sdk-parity-matrix.md` for t per-language surface. **`Requester.billing_ref` removed (breaking, pre-1.0).** The caller-written -billing label on `Requester` is gone; field number 5 and the name are -`reserved` so they can never be reused with a different meaning. Nothing read -it: billing and cost attribution key on the verified caller identity and the +billing label on `Requester` is gone; the field is deleted outright with no +`reserved` statement — pre-v1 the number returns to the free pool, and +`reserved` becomes the tool for field removals only once v1.0.0 is tagged. +Nothing read it: billing and cost attribution key on the verified caller identity and the account handle minted at `Register` (`RegisterResponse.billing_ref`), which the Exchange resolves from the request signature — never from anything the caller sends. Dropping the field also removes the name collision between the diff --git a/proto/ramp/v1/ramp.proto b/proto/ramp/v1/ramp.proto index 266a938..43f6362 100644 --- a/proto/ramp/v1/ramp.proto +++ b/proto/ramp/v1/ramp.proto @@ -1435,13 +1435,6 @@ message Requester { // Human-readable name (e.g., "Acme Research Assistant"). optional string name = 4; - // Field 5 was a caller-written billing label. Removed: billing and cost - // attribution key on the verified caller identity and the account minted at - // Register, never on anything the caller writes into the request. Reserved - // so the number and name can never be reused with a different meaning. - reserved 5; - reserved "billing_ref"; - // Entitlement scopes. Declare what the requester can access. // // The Exchange filters its catalog to resources matching these scopes. diff --git a/website/src/content/docs/reference/changelog.mdx b/website/src/content/docs/reference/changelog.mdx index ca2e180..457d64e 100644 --- a/website/src/content/docs/reference/changelog.mdx +++ b/website/src/content/docs/reference/changelog.mdx @@ -33,9 +33,10 @@ in Python; `parseErrorDetail` / `errorDetailFrom` in TS). The SSRF-guarded trans is a single env-driven client governed by two flags (`SKIP_SSRF`, `ALLOW_INSECURE`). **`Requester.billing_ref` removed (breaking, pre-1.0).** The caller-written -billing label on `Requester` is gone; field number 5 and the name are -`reserved` so they can never be reused with a different meaning. Nothing read -it: billing and cost attribution key on the verified caller identity and the +billing label on `Requester` is gone; the field is deleted outright with no +`reserved` statement — pre-v1 the number returns to the free pool, and +`reserved` becomes the tool for field removals only once v1.0.0 is tagged. +Nothing read it: billing and cost attribution key on the verified caller identity and the account handle minted at `Register` (`RegisterResponse.billing_ref`), which the Exchange resolves from the request signature — never from anything the caller sends. Dropping the field also removes the name collision between the