feat: parity with @dodomain/node 0.6.0 — TLS-issuance advisories and the ConnectSessionSummary rename (0.4.0) - #4
Merged
Conversation
…the ConnectSessionSummary rename (0.4.0)
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
Brings the Python SDK back to the parity rule in the monorepo's
RUNBOOK.md§8.4 — "the Python SDK tracks@dodomain/node's public surface — when an API contract changes here, BOTH SDKs move." PyPIdodomain-sdkwas at 0.3.0 (parity with@dodomain/node0.4.0) while node has since shipped 0.5.0 and 0.6.0. This isdodomain-sdk0.4.0.Additive apart from one rename that keeps a working alias, so upgrading from 0.3.0 is a drop-in.
The surface diff this mirrors
Diffed
packages/node/srcbetween23b01ea(node 0.4.0, 2026-08-20) and587e633(node 0.6.0, 2026-09-03), and the committedapps/docs/public/openapi.jsonover the same window. The/v1contract delta is exactly six items — every one of them additive except the rename:1400d94)Session→ConnectSessionSummary, deprecatedSessionalias kept,CreateSessionResponsealias re-pointedConnectSessionSummary+Session = ConnectSessionSummary(same class object)587e633)TlsIssuanceAdvisorytypeTlsIssuanceAdvisory+TlsIssuanceAdvisoryCode/TlsIssuanceAdvisorySeverityIntegratorSession.tlsIssuanceAdvisories(required)IntegratorSession.tls_issuance_advisoriesApp.tlsIssuerCa: string | null(required)App.tls_issuer_caVerifySessionResponse.advisories(required)VerifyResult.advisoriesf092cb3(2026-08-27)VerifySessionResponse.records[].authoritativeFound+publicFound(required)VerifyRecord.authoritative_found/.public_foundItem 6 has no
@dodomain/nodetwin and is easy to miss:@dodomain/nodeexposes no verify method (POST /v1/sessions/{token}/verifyis token-public), so that contract change never moved a node version. This SDK does wrap it, so a node-only diff would have left the Python verify result silently two fields short. Found via the OpenAPI diff, not the node diff.Webhook side:
connection.verifiedandsession.completednow carrytlsIssuanceAdvisorieswhen non-empty (absent, not empty, when there is nothing to say). This SDK ships no typed event parser on purpose, so that is a documentation change here, not a code one.Deprecation policy
Matches node's exactly:
Sessionstays as an alias bound to the same class object —isinstance, equality and existingfrom dodomain import Sessionimports are unaffected — is marked deprecated in the docstring, README and changelog, and goes away in the next major.tests/test_models.py::test_the_deprecated_session_alias_is_the_same_class_not_a_copypins that it never forks into a second class, which is the Python analogue of node'sMutuallyAssignable<Session, ConnectSessionSummary>type pin.Mechanical parity guard (new)
tests/fixtures/openapi_v1_shapes.jsonis a verbatim extract of the published OpenAPI component schemas forPOST /v1/sessions,GET /v1/sessions/{token}(both arms),POST /v1/sessions/{token}/verifyandGET /v1/apps, taken from the monorepo's committedapps/docs/public/openapi.json— which is itself generated from the same zod schemas the handlers validate with.tests/test_openapi_contract.pythen asserts two things per schema:requiredlist (a newly-required API field fails the suite the moment the fixture is regenerated), andSame job
tests/fixtures/webhook_vectors.jsonalready does for the signer. Both directions were proven red before being left green:tls_issuer_ca=_opt_str(data, "tlsIssuerCa")fromApp._from_api→AssertionError: ListAppsResponse.apps.items.tlsIssuerCa did not reach .tls_issuer_ca / assert None == 'sample-tlsIssuerCa'"tlsIssuerCa"from the map (simulating a new required field nobody modelled) →AssertionError ... Extra items in the left set: 'tlsIssuerCa'The regeneration recipe is in the test module's docstring.
Tolerance
Every new field follows the module's existing rule (
_opt_list/_opt_str): a body recorded before the field existed still parses (as()/None), while a field that is present with the wrong type is still fatal. Covered bytest_a_verify_response_recorded_before_advisories_existed_still_parses, its two siblings, andtest_an_advisories_field_that_is_present_but_not_an_array_is_still_fatal.Gates (run locally, verbatim from
.github/workflows/ci.yml)383 tests (was 359). Only Python 3.13 is installed on the authoring host, so the matrix's 3.10 leg was not run locally — CI covers it, and
tytype-checks against 3.10 ([tool.ty.environment] python-version = "3.10") and passes. No 3.11+ syntax was introduced.The
e2e-testjob needs theDODOMAIN_SECRET_KEYsecret and hits prod; unchanged by this PR and not run locally.Release order and the exact dispatch step — DO NOT run these from this PR
Publishing is operator-only (monorepo
CLAUDE.md, hard boundaries). Nothing here has been tagged and nothing has touched PyPI.@dodomain/node0.6.0 must ship first; Python tracks it.node scripts/sdk/sync-mirror.mjsfrom the repo root, then inDevinoSolutions/dodomain-sdk: Actions → Release (npm) → Run workflow → modepublish→ packagenode. Or:npm view @dodomain/node version→0.6.0, with provenance.mainhere.main, dispatch its ownpublish.yml(workflow_dispatch, no inputs) — it ships whatever version is insrc/dodomain/__init__.py, which this PR sets to0.4.0, over PyPI trusted publishing (OIDC, no token):pip index versions dodomain-sdk(or the PyPI project page) shows0.4.0. Remember the distribution name isdodomain-sdkand the import name isdodomain.Finding: dev-dependency pins are behind
Checked PyPI today.
httpx,pytest,pytest-asyncio,pytest-covandrespxare all pinned at their current latest. Two are not:ruff==0.16.1→ latest 0.16.6ty==0.0.66→ latest 0.0.79Deliberately not bumped here: a linter/type-checker bump introduces churn and new diagnostics unrelated to a parity release, and would make this diff harder to review. It wants its own PR.