Skip to content

feat: SDK conformance wave 2 — twilio-go, go-shopify, google idtoken - #65

Merged
deblasis merged 2 commits into
mainfrom
feat/sdk-conformance-wave2
Aug 18, 2026
Merged

feat: SDK conformance wave 2 — twilio-go, go-shopify, google idtoken#65
deblasis merged 2 commits into
mainfrom
feat/sdk-conformance-wave2

Conversation

@deblasis

Copy link
Copy Markdown
Contributor

What

SDK conformance wave 2 — three more SDKs driving stunt adapters, 15 new checks (34 total across six SDKs), all green under -race.

SDK Adapter Checks
twilio-go twilio-style create, queued → sent → delivered lifecycle via SDK Fetch polling, the +15005550001 magic number → failed, list To-filter, status callbacks verified against Twilio's documented HMAC-SHA1 formula
go-shopify (bold-commerce) shopify-style webhook registration, order creates, page_info cursor pagination through the SDK's NextPageOptions Link walking, and deliveries verified by the SDK's own VerifyWebhookRequest HMAC validator
google-api-go-client/idtoken + x/oauth2 google-style authorization-code exchange, refresh with rotation, userinfo, and the marquee: idtoken.Validate — Google's own RS256+JWKS verifier — accepting the adapter-minted id_token against the adapter-served /oauth2/v3/certs

New harness capability: a shared host-rewriting RewriteClient — the seam for SDKs that hardcode their provider host but accept a custom http.Client (twilio-go BaseClient, go-shopify WithHTTPClient). Safe only for SDKs that don't sign request URLs; both qualify.

Six real bugs found and fixed

  1. twilio mock auth token had underscores. Official SDKs validate credentials as alphanumeric client-side — twilio-go rejected them (error 21224) before any request. Now a real-looking 32-hex token (documented; a breaking change for anyone hardcoding the old value).
  2. twilio API versioned /2010-06-01/ — the real API and every SDK use /2010-04-01/. All routes renamed.
  3. twilio status callbacks delivered the stunt {type,payload} envelope instead of Twilio's callback shape — real receivers could never verify them. Now the message resource as form params, signed base64(HMAC-SHA1(token, url + sorted key/value pairs)) via events_emit_raw; the lifecycle engine test verifies every callback's signature.
  4. shopify webhook ids and embedded customer ids rendered as JSON strings — typed SDKs reject the response (ids coerced to numeric, mirroring the existing _num_id pattern).
  5. google token endpoint rejected HTTP Basic client credentials (RFC 6749 §2.3.1) — x/oauth2's default style. Worse, the single-use code was burned on the first (failing) attempt so the library's auto-retry could never succeed. Both grant types accept Basic or form creds now.
  6. (harness-side) the authorize redirect is followed by default — the no-redirect client pins the first hop.

Verification

  • 34 conformance checks green under -race (six SDKs).
  • Full main-module suite, parse guard, QC boot, the all-adapter input-safety sweep, gofmt, vet — green.

15 new conformance checks (34 across six SDKs), all green under -race:

- twilio-go: create, queued->sent->delivered lifecycle via SDK Fetch
  polling, the +15005550001 magic number -> failed, list To-filter, and
  status callbacks verified against Twilio's documented HMAC-SHA1
  formula.
- go-shopify (bold-commerce): webhook registration, order creates,
  page_info cursor pagination through NextPageOptions Link walking, and
  deliveries verified by the SDK's own VerifyWebhookRequest.
- google-api-go-client/idtoken + x/oauth2: authorization-code exchange,
  refresh with rotation, userinfo, and idtoken.Validate — Google's own
  RS256+JWKS verifier — accepting the adapter-minted id_token against
  the adapter-served /oauth2/v3/certs.

Six real bugs found and fixed:
1. twilio mock auth token had underscores — SDKs validate alphanumeric
   client-side and rejected it (now a real-looking 32-hex; documented).
2. twilio API versioned /2010-06-01/ — the real API and every SDK use
   /2010-04-01/ (all routes renamed).
3. twilio status callbacks delivered the stunt envelope, not Twilio's
   form-param callback shape + url+sorted-key/value signature — real
   receivers can now verify (events_emit_raw; lifecycle test verifies
   every signature).
4. shopify webhook ids + embedded customer ids rendered as JSON strings
   (typed SDKs reject; now numeric).
5. google token endpoint rejected RFC 6749 §2.3.1 HTTP Basic client
   credentials — x/oauth2's default style — and burned the single-use
   code on the first attempt so its retry could never succeed.
6. google authorize redirect followed by test clients (harness fix:
   no-redirect client for the hop).
…ardening

Review findings on PR #65, all fixed:

- CRITICAL: the numeric customer-id fix crashed on the most common
  Shopify pattern — Order.Create with an embedded customer sends the id
  as a JSON number (a Starlark float), and the string-only id parser
  raised, 500ing the create AND poisoning every later order list (the
  broken order rendered on every read). _num_id is now total over the
  shapes an id takes (stored string, JSON int, JSON float), and the
  conformance suite pins the embedded-customer create.
- Fulfillment/transaction/variant ids: the same string-id class was
  still live on those surfaces. Fulfillments and transactions now store
  string ids (matching _derive_financial's comparisons — an earlier cut
  stored numeric order_ids and broke financial_status derivation) and
  render numeric views on the wire, webhook payloads included; variant
  ids coerce in the product view.
- twilio _form_encode: a byte-exact table is impossible (Starlark
  rejects \x80+ escapes; ord() is rune-based), and the naive index
  crashed on any non-ASCII From/To byte, permanently 500ing reads of
  that message. Callback params are now sanitized to printable ASCII so
  the signature string and the encoded body always agree — receivers
  still verify; real sender IDs are ASCII.
- twilio README: the documented Basic-auth blob still encoded the
  RETIRED underscore token (plain-text grep missed it); regenerated.
  The signature section now documents the real formula (form params,
  url + sorted key/value) instead of the envelope-body scheme this PR
  replaced. adapters/README roster row updated to match.
- Misleading 2010-06-01 example comments in adapter.go/lint.go updated.
- Tests: twilio poll drives to delivered (both callbacks fire, no more
  guaranteed 10s spin); shopify sink slice is mutex-guarded (-race);
  google gains a tampered-token negative (idtoken.Validate must reject);
  null customer round-trips as null instead of {}.

36 conformance checks green under -race; full main-module suite green.
@deblasis
deblasis merged commit 629c066 into main Aug 18, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant