Wire-contract parity: per-call host resolution, sync checkout_decide, and dropoff_latitude - #101
Draft
tomas-amaro wants to merge 3 commits into
Draft
Wire-contract parity: per-call host resolution, sync checkout_decide, and dropoff_latitude#101tomas-amaro wants to merge 3 commits into
tomas-amaro wants to merge 3 commits into
Conversation
Two wire-contract parity defects from docs/parity/FLEET.md sections 3 and 6. 1. Sticky host selection. AbstractTransport::$url was reassigned in place by decideOrder, eligible, opt_in and all eight account methods, and never restored. Once an instance called login(), every later call on it - including submitOrder() - went to api.riskified.com, silently cross-posting order data to the Account Secure host. The host family is now scoped to the single call that asked for it (on_host()), and endpoint_prefix() resolves the host through host() per request. $url is now written only by the constructor. The public API is unchanged: no constructor, method name, or signature moved. 2. dropoff_latitiude. LineItem declared the corrected spelling dropoff_latitude, which the API does not read, so ride-hailing dropoff geolocation was dropped without an error. The live wire name is the transposed dropoff_latitiude - see docs/flows/01-model-catalog.md section 5 and sdk_net @ 9165cf5 OrderElements/RideTicketLineItem.cs:101. Restored, with a comment and a test asserting the misspelling so it is not "corrected" again. Regression tests: tests/OrderWebhook/Transport/HostSelectionTest.php (with a RecordingTransport double that records the URL each call would have used) and tests/OrderWebhook/Model/LineItemTest.php. Both fail at c0b0f87. Null handling, the vendor Accept header, api-version, hash_equals, old_status, error parsing, retries and timeouts are deliberately untouched.
…to sync Two follow-ups to the previous commit. 1. A general field-alias mechanism, so restoring the dropoff_latitiude wire name is no longer a caller-visible break. AbstractModel gains $_field_aliases, an alias => canonical field map consulted by the constructor, __set and __get through resolve_field(). A value written through an alias is stored, validated and serialized under the canonical field name, so an alias can never add, duplicate or rename a key on the wire. Writing through one raises E_USER_DEPRECATED naming the field to use; reads are silent, to avoid repeating the same signal. Unknown properties still throw InvalidPropertyException. LineItem declares the one alias we need today, dropoff_latitude => dropoff_latitiude; no other field is retrofitted. 2. checkout_decide() now resolves the sync host, like decideOrder(). It posts to /api/decide, and the C# reference has exactly one /api/decide call site, unconditionally FlowStrategy.Sync (sdk_net @ 9165cf5, Orders/OrdersGateway.cs:142 - the full BuildUrl inventory confirms there is no checkout-specific decide on FlowStrategy.Default). In production it was posting to wh.riskified.com; sandbox is unaffected, having no sync host. Cross-checking every PHP endpoint against that inventory turned up no other unwrapped call to a path an on_host() family serves. The wire payload is unchanged: an order serialized before and after this commit is byte-identical, and against c0b0f87 the only difference in the whole tranche is the single dropoff_latitiude key. Null handling and the always-emitted defaults remain untouched.
…me and the alias
Reverts the two dropoff changes made earlier on this branch: the rename of
`dropoff_latitude` to `dropoff_latitiude`, and the `$_field_aliases` machinery
added to keep the correct spelling working as a deprecated input name.
Both rested on a contract-corpus claim that the transposed `dropoff_latitiude`
was the live wire name, because the reference C# SDK sends it. That inference
was wrong:
* Both OpenAPI specs declare `dropoff_latitude`, with a description and an
example. The transposed spelling appears in neither.
* It occurs exactly once in all of sdk_net
(Riskified.SDK/Model/OrderElements/RideTicketLineItem.cs:100), with no test
covering it, while pickup_latitude (:89) and dropoff_longitude (:104) in the
same class are spelled correctly.
This SDK already had the name right. The rename would have broken a field that
worked, and the alias existed only to soften that break.
* LineItem: field restored to `dropoff_latitude`; the alias map removed.
* AbstractModel: restored to master. The whole alias mechanism -- the
resolve_field indirection through __get/__set/__construct and the
E_USER_DEPRECATED path -- had exactly one consumer, so it is dead code now
rather than a general facility.
* LineItemTest: the alias and deprecation tests are gone. What replaces them
asserts `dropoff_latitude` is the emitted key and `dropoff_latitiude` is
not, that the transposed name is rejected as an unknown property, and that
all four ride geolocation fields use their contract names. The
unknown-property coverage of AbstractModel is kept -- master had none.
The corpus has been corrected in Riskified/sdk-orchestrator.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
Wire-contract parity fixes for the PHP SDK, derived from the language-neutral
Riskified contract corpus and audited against the C# reference implementation
(
Riskified/sdk_net@9165cf5). Two commits, production source plus regressiontests.
Changes
Sticky host selection (data-leak class)
AbstractTransport::$urlwas reassigned in place bydecideOrder,eligible,opt_inand all eight account methods, and never restored. Once an instance calledlogin(), every later call on it — includingsubmitOrder()— went toapi.riskified.com, silently cross-posting order data to the Account Secure host.The host family is now scoped to the single call that asked for it (
on_host()), andendpoint_prefix()resolves the host throughhost()per request.$urlis written only by the constructor. The public API is unchanged: no constructor, method name, or signature moved.checkout_decide()posted to the wrong production hostIt posts to
/api/decide, and the C# reference has exactly one/api/decidecall site, unconditionallyFlowStrategy.Sync(Orders/OrdersGateway.cs:142). In production it was posting towh.riskified.com; sandbox is unaffected, having no sync host. Cross-checking every PHP endpoint against the fullBuildUrlinventory turned up no other unwrapped call to a path anon_host()family serves.dropoff_latitude— reverted, this SDK was already correctAn earlier revision of this branch renamed
LineItem'sdropoff_latitudeto the transposeddropoff_latitiude, and added a$_field_aliasesmechanism toAbstractModelso the correct spelling kept working as a deprecated input name. Both have been reverted.The rename rested on a contract-corpus claim that the transposition was the live wire name, on the grounds that the reference C# SDK sends it. That inference was wrong:
dropoff_latitude, with a description and an example. The transposed spelling appears in neither, nor anywhere else in the reference export.sdk_net(OrderElements/RideTicketLineItem.cs:100), with no test covering it, whilepickup_latitude(:89) anddropoff_longitude(:104) in the same class are spelled correctly.So the transposition is a defect in the C# SDK, not the contract. This SDK had the name right; the rename would have broken a field that worked, and the alias existed only to soften that break.
AbstractModelis restored tomaster— theresolve_field()indirection and theE_USER_DEPRECATEDpath had exactly one consumer, so keeping them would leave dead code rather than a general facility.The corpus has been corrected in
Riskified/sdk-orchestrator.Tests
tests/OrderWebhook/Transport/HostSelectionTest.php, with aRecordingTransportdouble that records the URL each call would have used.tests/OrderWebhook/Model/LineItemTest.php— assertsdropoff_latitudeis the emitted key anddropoff_latitiudeis not, that the transposed name is rejected as an unknown property, and that all four ride geolocation fields use their contract names. Guarded in both directions, since this branch pinned it the wrong way once.Both are reported to fail at
c0b0f87.Deliberately unchanged
Null handling and the always-emitted defaults, the vendor
Acceptheader,api-version,hash_equals,old_status, error parsing, retries and timeouts.An order serialized before and after this branch is byte-identical: no payload key changes in either direction. (An earlier revision of this branch changed one —
dropoff_latitude→dropoff_latitiude— and that has been reverted.)Reviewer notes
c0b0f87and is one commit behindmaster(3b6652e). It merges cleanly.🤖 Generated with Claude Code