Repository navigation
release: 2.6.0 — post-v2.5 independent reviewer audit closure (#295-#301) - #310
Conversation
#301) 7 issues across security, HTTP transport, WebSocket reliability, models/types, REST resources, performance, and docs — identified by a fresh 7-agent parallel review on top of the v2.5 closure and executed across 3 sequential waves in disjoint git worktrees. Two breaking changes folded in: - int request fields reject bool across V1+V2 via new kalshi.StrictInt (#295) - KALSHI-ACCESS-* in extra_headers rejected at construction + per-request (#298) Critical fixes: - WS session re-entry guard with state reset on partial connect failure (#297) - Case-insensitive transport header merge + explicit Content-Type pin on JSON body helpers, closing a wire-level auth-header forge surface (#298) Performance: - Orderbook snapshot identity adoption restored on the recv-loop bypass while the public apply_snapshot keeps its defensive copy (#296) Polish: - Sync/AsyncTransport.close() explicitly idempotent (#301) - docs/resources/orders.md drops stale defaults-to-buy comment (#299) - docs/configuration.md reference table completed (#300) Closes #295, #296, #297, #298, #299, #300, #301.
Code Review — PR #310: release 2.6.0This is a release-commit PR: the diff itself is CHANGELOG, ROADMAP, migration docs, and version bumps. The real substance is in the 7 already-merged component PRs (#303–#309). I reviewed the actual implementation of each wave. OverviewClean, well-structured release. Two breaking changes with genuine safety value, one performance restoration, two correctness fixes, and two polish items. All waves executed in disjoint worktrees; the approach is sound. Wave 1 —
|
| Area | Verdict |
|---|---|
| Code correctness | ✅ All implementations verified correct |
| Project conventions | ✅ StrictInt pattern, extra="forbid" on Request models, _closed flag |
| Security (auth forge surface) | ✅ Closed at both construction and per-request call sites |
| Performance (orderbook) | ✅ Identity adoption restored on hot path |
| Test coverage | ✅ Each PR includes targeted regression/pinning tests |
| Breaking change docs | ✅ Migration guide is complete and accurate |
Recommend approval. One actionable suggestion before the v2.6.0 tag:
- Consider adding a one-liner warning in the
subscribe_orderbook_deltadocstring about the snapshot aliasing hazard (perf(ws): _apply_snapshot_inplace dict() copy nullifies #263 identity-adoption speedup #296), since the migration guide alone won't be seen by users who don't upgrade. Low severity, but the mutation-through-reference footgun is real.
|
Bot recommends approval. The one actionable item — "consider adding a one-liner warning in Merging. The |
7 issues across security, HTTP transport, WebSocket reliability, models/types, REST resources, performance, and docs — identified by an independent 7-agent review of v2.5.0 and executed across 3 sequential waves (W0 docs, W1 money/correctness, W2 polish) in disjoint git worktrees. 7 PRs merged ahead of this release commit.
Wave summary
Breaking changes
intrequest fields rejectbool(bug:int-typed request fields silently coercebool(subaccount routing, transfers, counts) #295) — every money-routing / counting integer of every Request model now useskalshi.StrictInt.boolis anintsubclass and used to silently coerce True→1 / False→0, misroutingsubaccount/from_subaccount/amount_cents/count/etc. Now raisesValidationError.KALSHI-ACCESS-*rejected inextra_headers(bug(transport): case-mismatchedextra_headerskeys leak alongside auth/body Content-Type on the wire #298) — rejected at bothKalshiConfig(extra_headers=)construction and per-requestextra_headers=kwargs. The previous case-sensitive merge let a caller-supplied lowercasekalshi-access-keyco-exist with the SDK-signed uppercase one on the wire.Migration guide:
docs/migration.mdv2.5 → v2.6 section covers both fences and the raw-subscribe_orderbook_deltaaliasing note.Verification
uv run mypy kalshi/clean (76 files)uv run ruff check .cleanuv run pytest tests/— W1 / W2 commits brought the count to 2780+ passingCloses
Closes #295. Closes #296. Closes #297. Closes #298. Closes #299. Closes #300. Closes #301.
Release tag: not pushed yet. After this PR merges, the
v2.6.0tag is what triggers the.github/workflows/release.ymlworkflow which builds the wheel, runstwine check, and publishes to PyPI via OIDC. Tag intentionally deferred so the maintainer reviews + approves the actual PyPI publish.