release: v2.2.0#170
Conversation
Cuts v2.2.0 — the response-side spec drift hardening stack (#157). Version bumps: - pyproject.toml: 2.1.0 → 2.2.0 - kalshi/__init__.py: 2.1.0 → 2.2.0 Docs: - CHANGELOG.md: finalize ## Unreleased → ## 2.2.0 — 2026-05-19 with a release-summary headline. The Added/Changed/Fixed entries written incrementally across #166–#169 stay as-is. - ROADMAP.md: add v2.2.0 to Shipped with a coverage summary; drop the two "Next milestone" items now done by this release (response-side drift detection; WS envelope extra=allow); add two new follow-ups (map remaining REST sub-models into CONTRACT_MAP; required-but- optional drift policy decision). - CLAUDE.md: active milestone → post-v2.2. Release scope (65 new optional fields + warn→fail flip + 1 bugfix): - REST response models: Market +11, Order +8, Fill +4, Event +3, EventMetadata +2, Settlement +1, Trade +2, IncentiveProgram +1, RFQ +1, Quote +3, OrderGroup +1, GetOrderGroupResponse +1, CreateOrderGroupResponse +2 (#166, #167, #168). - WS payload models: 33 fields across 11 payloads — Unix-ms timestamps (`*_ts_ms`), outcome_side/book_side direction encoding, MVE linkage, RFQ/Quote context echoes (#168). - Test infrastructure: additive drift now hard-fails CI; unmapped WS models hard-fail; required-but-optional stays warn-only (~204 entries, separate policy decision). EXCLUSIONS allowlist wired through response-side checks (#165). ErrorPayload registered in WS_CONTRACT_MAP; WS envelopes/helpers all use extra=allow (#168). - Bugfix: dropped le=32 cap on 6 subaccount request fields; demo allocates ephemeral subaccount numbers above 32 (observed 41 in nightly, 44 locally). Spec defines no upper bound (#169). No API breaks. All changes additive or relaxing. Bump is semver-minor. Verification: - uv run pytest tests/ --ignore=tests/integration -q -> 2023 passed, 35 warnings (all required-drift, kept warn-only) - uv run pytest tests/integration/test_subaccounts.py::TestSubaccountsSync::test_transfer_between_subaccounts -> 1 passed against live demo (#164 unblocked end-to-end) - uv run mypy kalshi/ -> Success: no issues found in 76 source files - uv run ruff check . -> All checks passed! - kalshi.__version__ check -> 2.2.0 After merge, push tag v2.2.0 to trigger the release workflow (.github/workflows/release.yml): build sdist+wheel → PyPI trusted- publish → GitHub release with CHANGELOG section as notes.
Code Review — v2.2.0 Release CutThis is a clean, minimal release PR. The five changed files are all docs and version bumps; the actual code shipped in #165–#169. Review notes below are ordered by importance. CorrectnessField-count discrepancy in the PR body (informational) The PR body's summary table says CHANGELOG date vs. merge date The changelog is stamped Version bumpsBoth Semver claimClaimed as minor. The PR body enumerates: new optional fields (additive), relaxed Documentation changesCHANGELOG.md — Upgrading ROADMAP.md — The shipped v2.2.0 entry is well-summarised. Removing the two completed "Next milestone" items and promoting new follow-ups (REST sub-model mapping pass, required-but-optional drift policy) keeps the backlog honest. The reformatting of deferred items with bold labels improves scannability. ✓ CLAUDE.md — Milestone updated from Release workflowThe post-merge tag instruction ( SummaryThe PR is release-ready modulo two low-severity documentation notes:
|
Cuts v2.2.0 — the response-side spec drift hardening stack (#157).
Version bumps
pyproject.toml: 2.1.0 → 2.2.0kalshi/__init__.py: 2.1.0 → 2.2.0Semver: minor
All changes since v2.1.0 are additive or relaxing:
le=32constraint dropped on 6 subaccount request fields (only callers passing > 32 were affected, and those round-tripped to the server anyway).extra="allow"(relaxes tolerance, never tightens).No API breaks. No migration required.
Release scope
*_ts_mstimestamps,outcome_side/book_sidedirection encoding, MVE linkage, RFQ/Quote context echoes)ErrorPayloadregistered inWS_CONTRACT_MAP; envelopes + helpers all useextra="allow"le=32cap on 6 subaccount request fields (demo allocates above 32; spec has no upper bound)PRs in this release: #165 (PR0), #166 (PR1), #167 (PR2), #168 (PR3+4+5), #169 (#164 fix).
Docs touched
## Unreleased→## 2.2.0 — 2026-05-19with a release-summary headline. The Added/Changed/Fixed entries written incrementally across feat(models): backfill v3.18.0 fields on Market / Order / Fill (PR1) #166–fix(models): relax subaccount-number request constraint (drop le=32) (#164) #169 stay as-is.extra=allow); added two new follow-ups (REST sub-model mapping pass; required-but-optional drift policy).post-v2.2.Verification
The 35 warnings are all
test_required_drift/test_ws_required_drift— the required-but-optional axis stays warn-only per the issue stack's explicit out-of-scope note.Release workflow
Once squash-merged, push tag
v2.2.0to trigger.github/workflows/release.yml:pyproject.tomlversion (gate).uv build.twine checkthe artifacts.## 2.2.0 — ...CHANGELOG section as notes.No manual PyPI upload needed.