From 7e4237dbd3ab72785e819d02aabb6a5928f89747 Mon Sep 17 00:00:00 2001 From: Jeff West Date: Tue, 19 May 2026 19:01:53 -0500 Subject: [PATCH] release: v2.2.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- CHANGELOG.md | 8 ++++++-- CLAUDE.md | 2 +- ROADMAP.md | 39 ++++++++++++++++++++++++++------------- kalshi/__init__.py | 2 +- pyproject.toml | 2 +- 5 files changed, 35 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad32c7b..b8cc9a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,14 @@ All notable changes to kalshi-sdk will be documented in this file. -## Unreleased +## 2.2.0 — 2026-05-19 Response-side spec drift hardening stack (#157). Backfills the remaining -v3.18.0 / v0.14 fields and promotes additive drift to a hard CI failure. +v3.18.0 OpenAPI / v0.14 AsyncAPI fields across REST and WebSocket response +models (65 new optional fields across 16 models), promotes additive +drift from warning to hard CI failure, and lands a high-signal bugfix +for the subaccount-number request constraint that was rejecting valid +server-assigned values. ### Added diff --git a/CLAUDE.md b/CLAUDE.md index 19c5c5b..2286d35 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -134,7 +134,7 @@ All work — bugs, enhancements, polish, spec drift — is tracked in **GitHub I on `TexasCoding/kalshi-python-sdk`. Use the `gh` CLI or the GitHub UI; do not add markdown trackers (TODOS/BACKLOG) back to the repo. -- Active milestone: post-v2.0 (after the audit-driven hardening wave that shipped v2.0.0) +- Active milestone: post-v2.2 (after the response-side spec drift hardening stack that shipped v2.2.0) - Labels in use: `bug`, `enhancement`, `documentation`, `polish`, `breaking`, `spec-drift`, `testing`, `infra`, `ws`, `cli` - `ROADMAP.md` — short pointer to the active milestone - `CHANGELOG.md` — release-facing history; updated per release diff --git a/ROADMAP.md b/ROADMAP.md index 9b6916d..8c99886 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -4,6 +4,18 @@ See `CHANGELOG.md` for full release history. +- **v2.2.0 (2026-05-19)** — response-side spec drift hardening (`#157`). + 65 new optional fields backfilled across 16 REST + WS response models + for OpenAPI v3.18.0 / AsyncAPI v0.14 (`Market`, `Order`, `Fill`, + `Event`, `EventMetadata`, `Settlement`, `Trade`, `IncentiveProgram`, + `RFQ`, `Quote`, `OrderGroup` + 3 group responses, plus 11 WS payloads + including the new `*_ts_ms` Unix-ms timestamps and + `outcome_side` / `book_side` direction encoding). Promoted additive + drift from warn → hard fail in CI so the next missed field surfaces + loudly. Relaxed the request-side `le=32` cap on six subaccount fields + (demo allocates above 32). Registered `ErrorPayload` in + `WS_CONTRACT_MAP`; applied `extra="allow"` to all WS envelope and + helper classes to match the payload policy from `#143`. - **v2.1.0 (2026-05-18)** — OpenAPI sync v3.13.0 → v3.18.0 (`#155`). V2 event-market orders family (`create_v2` / `amend_v2` / `decrease_v2` / `cancel_v2` + batched variants on `/portfolio/events/orders/*`), @@ -47,20 +59,21 @@ See `CHANGELOG.md` for full release history. Not scoped. Carry-overs from v2.1 and v2.0 audit backlog: -- **Response-side spec drift detection.** v2.1 contract tests cover request - bodies (`TestRequestBodyDrift`) but not response models, which is how - `Balance.balance_dollars` slipped through 5 rounds of review. Add a - `RESPONSE_MODEL_MAP` + walker that asserts spec-required fields exist on - the SDK model. - -- Apply `extra="allow"` policy to WS envelope models (`kalshi/ws/models/`) - to mirror the response-model uniformity from `#114`. -- `MessageQueue._buffer = collections.deque(maxlen=maxsize+1)` for +- **`MessageQueue._buffer = collections.deque(maxlen=maxsize+1)`** for defense-in-depth (#106 F-P-15 / F-R-02). -- `_to_decimal_dollars` / `_to_decimal_fp` consolidation (#106 F-N-09 + - the follow-up noted in #140). -- WS UX foot-guns: auto-start recv loop when no `subscribe_*` was called, - resubscribe-time data-frame stashing (#106 F-P-16 / F-R-13). +- **`_to_decimal_dollars` / `_to_decimal_fp` consolidation** (#106 + F-N-09 + the follow-up noted in #140). +- **WS UX foot-guns**: auto-start recv loop when no `subscribe_*` was + called, resubscribe-time data-frame stashing (#106 F-P-16 / F-R-13). +- **Map remaining REST sub-models / V2 family / internal containers** + (~42 entries) into `CONTRACT_MAP` and promote + `test_contract_map_completeness` (REST) to hard-fail. WS side already + hard-fails as of v2.2.0; the REST side stays warn-only until the + mapping work lands. +- **Required-but-Optional drift policy decision** (~204 entries on + `test_required_drift` / `test_ws_required_drift`). Currently warn-only; + promote to fail behind either an allowlist or a tightening pass that + drops `None` defaults on fields the server reliably sends. Pick from `gh issue list` and the deferred items in `#106` opportunistically. diff --git a/kalshi/__init__.py b/kalshi/__init__.py index 5c5a968..acffd99 100644 --- a/kalshi/__init__.py +++ b/kalshi/__init__.py @@ -318,4 +318,4 @@ "Withdrawal", ] -__version__ = "2.1.0" +__version__ = "2.2.0" diff --git a/pyproject.toml b/pyproject.toml index 22e95a4..dd1dd32 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "kalshi-sdk" -version = "2.1.0" +version = "2.2.0" description = "A professional Python SDK for the Kalshi prediction markets API" readme = "README.md" license = { text = "MIT" }