Repository navigation
feat(sdk): Hybrid Link tier transitions (resolution, merge, candidates) - #304
Merged
Merged
Conversation
Type hybridResolution (keep/split) and hybridMerge on tier quotes, quote.hybridTransition with its status, Client.projects.listHybridMergeCandidates, and the hybrid_resolution_required / hybrid_transition_ineligible codes. Pin the Platform snapshot and ledger to API commit feaf0734a.
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (16)
✨ Finishing Touches📝 Generate docstrings
Comment |
Member
Author
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Candidate Numbers report canBeAbsorbed, ineligibleReason gains transition_in_progress, pairing_in_progress and hms_enabled, and the list returns 403 feature_unavailable without Hybrid Link access. Cloud credential operations carried in from API dev are excluded until SDK PR #308 merges.
The missing-choice code is hybrid_choice_required, which a rejected queued change also reports as its failureReason. The carried API dev revision adds campaign send windows, typed here, and Official API template, service-window and pricing reads excluded until SDK PR #308 merges.
SDK dev already types campaign send windows, so the duplicate fields from this branch are dropped in favour of dev's. The hosted Flow endpoint and Flow encryption key operations carried from API dev (PR #428) have no SDK owner yet and are excluded.
purpshell
marked this pull request as ready for review
October 2, 2026 01:56
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.
Adds TypeScript SDK support for Hybrid Link tier transitions: resolving a Hybrid Link Number that leaves Pro, merging a same-number pair on an upgrade to Pro, and listing merge candidates.
Client.sessions.quoteTierChangeacceptshybridResolution(discriminatedkeep/split) orhybridMerge(absorbNumberId).NumberTierQuoteRequestmakes them mutually exclusive at the type level. The method also rejects both at runtime, before any request, withPolymorfaValidationError.NumberTierChange.quote.hybridTransitionis a union discriminated onaction(keep/split/merge), withsurvivingNumberId,status(scheduled | running | completed | failed | cancelled),failureReason,newNumberId,metaDisconnectRequiredandeffectiveAtMs.Client.projects.listHybridMergeCandidates(projectId)forGET /platform/projects/{projectId}/hybrid-merge-candidates(ledger clientPathprojects.listHybridMergeCandidates). It returnsHybridMergeCandidate[].POLYMORFA_ERROR_CODESaddshybrid_choice_requiredandhybrid_transition_ineligible. Both are 409 responses, so they surface asPolymorfaConflictError.HybridTransport,HybridResolution,HybridKeepResolution,HybridSplitResolution,HybridMerge,NumberHybridTransition(+ keep/split/merge variants),NumberHybridTransitionStatus,HybridMergeCandidate,HybridMergeCandidateNumber,HybridMergeIneligibleReason.Contract pin
This branch merges SDK
devthroughorigin/devas of 2026-10-02, which pins APIdeve818ba6. SDKdevalready types campaign send windows, so this branch dropped its own duplicatesendWindowfields in favour of dev's.Both snapshots are byte-identical to
polymorfa/polymorfa@fcf7b21015dd185e987b5aa3580e8af5f4c7f1a4on brancht3code/hybrid-pro-downgrade(API PR #404). That commit is not merged to APIdev, sosource.jsonrecordspublished: false. The Messaging snapshot is byte-identical to SDKdev's pin.Platform changes against SDK
dev:The Hybrid Link contract, unchanged since
4be41e2b4.Four reviewed fingerprint changes:
quoteSessionTierChange,getSessionTierChange,setSessionTierOverride, and the excluded ConsoleupdateProject.Six operations from API
dev(API PR #428, hosted Flow endpoints):GET /platform/flows/{flowId}/endpointPUT /platform/flows/{flowId}/endpointDELETE /platform/flows/{flowId}/endpointGET /platform/flows/{flowId}/endpoint/receiptsGET /platform/flow-encryption-keysPOST /platform/flow-encryption-keys/rotateNo open SDK PR covers these. The ledger excludes them with that reason; they need a separate SDK change.
Strict ledger: 557 total, 421 covered, 136 excluded, 0 missing, 0 partial, 0 changed. Repin to the merged API
devcommit before merging this PR.Contract changes since the first revision:
d831bf9c6: each candidate Number has a requiredcanBeAbsorbed, false with hosted message storage, and that Number must be kept.ineligibleReasonaddstransition_in_progress,pairing_in_progressandhms_enabled. The candidate list returns403 feature_unavailablewithout live Hybrid Link access, which surfaces asPolymorfaAuthorizationError.4be41e2b4: the missing-choice code ishybrid_choice_required, the code API PR #381 already ships, replacinghybrid_resolution_required. A queued change that is rejected for that reason reportsstatus: "rejected"withfailureReason: "hybrid_choice_required"; this is documented on the type, in the README and in a test. The candidate operation's description now states the 403 and the survivor rule.Contract notes / ambiguities
PlatformAccessPublicError/PublicErrorenums. The error-code contract test counts them as "documented in prose", the same way it handlespayg_required/addon_required.hybrid_transition_ineligiblecarries its reason only in the message (Hybrid Link change unavailable: <reason>). The error envelope has no structured reason field, so the SDK does not parse it.ineligibleReasonenum (deletion_in_progress,transition_in_progress,pairing_in_progress,hms_enabled,not_coexistence,different_customer,connection_disabled,not_connected) differs from the design's list of quote-time reasons. The SDK types follow the schema.quote.hybridTransition.status. The design doc saysNumberTierChange.hybridTransition.status. The SDK follows the spec and the implementation. The spec also addscancelled, which the design does not list.NumberHybridTransitionin the schema is one flat object. The SDK narrows it to anactionunion that matches the API'shybridPlanView.Six-part assessment
fcf7b21owns handlers, authority, and the source spec.session tier quote/confirm/statusandsession hybrid-merge-candidates, and pins CI to this SDK commit (6271f47) until publication.packages/typescript/README.md"Hybrid Link Numbers",contracts/README.mdpin notes, and a CHANGELOG entry for the tier transitions. Public Mintlify docs belong to the API PR.messaging.hybrid-linkand keeps the downgrade guard ungated.admin-hybrid-linkview.Verification (Node 24.15, at
6271f47)npm run typecheck,npm run build:workspaces: passnpm testwith--testTimeout=60000(the host was heavily loaded): 131 files, 1445 tests passnpm run check:coverage(strict),check:functions,check:names,format:check: passnpm run lint: 0 errors, 2 existing warnings inerrors.tsNo live API, deployment, or package publication was exercised. Publishing is required before the CLI can move from the source pin to a registry pin.