Skip to content

Changelog

Release notes follow the Keep a Changelog format with sections for Added, Changed, Deprecated, Removed, Fixed, and Security.

This page renders the release notes inline.

Versioning

Kairos follows SemVer. The current line is pre-1.0; minor releases on the 0.1.x line are additive. The v1.0 release will mark the first stability-guaranteed surface.

SurfaceStability
Client, *Builder, *Spec, *TickPre-1.0; additive on minor bumps, breaking changes possible on 0.x minor bumps until v1.0.
Per-analytic Output field setPre-1.0; new fields are additive.
EmitPolicyWire, TimeframePre-1.0; additive.
LinkError taxonomyPre-1.0; #[non_exhaustive]; downstream match arms include a catchall _.

Unreleased

Changed

  • Typed callback consumption. The documented Rust consumption model is now a typed callback: the fluent chain ends in .on_event(|row: &<Camel>Row| …)?, which delivers each emission as a generated <Camel>Row struct and returns an EventSubscription handle with .unsubscribe(). Callbacks across the process share one delivery worker, and a panic in a callback is caught and counted rather than tearing down the stream. The raw Arrow batch surface (TickStream / next_update) is retained only as a hidden escape hatch for embedders that feed RecordBatches into a DataFrame engine themselves.
  • Fluent per-field setters. Per-analytic knobs are now set with chainable .<field>(value) setters (.window_size(60), .min_emit_interval_ms(5_000)) before the terminal .on_event. The .configure(|spec| …) closure is removed from the public surface.
  • Symbol-first builder. The target securities now move to the analytic accessor argument. client.greeks(["QQQ"]) replaces client.greeks().for_securities(["QQQ"]); a single bare symbol needs no brackets (client.gex("QQQ")); an option (root, expiration, right, strike) 4-tuple and a mixed list of symbols and tuples fold into the same argument. The separate .for_securities([...]) and .for_options([...]) builder steps are removed. .for_index(...), .for_sector(...), and .for_predicate(...) are unchanged and still chain; a predicate, index, or sector subscription with no named symbols takes an empty list (client.greeks([]).for_sector(...)).
  • client.market_data() replaces client.raw(). The market-data feed accessor is renamed; the per-kind accessors keep their names (stock_quotes, stock_trades, option_quotes, option_trades, index_trades).

v0.1.0 — inaugural release

The first shipped Kairos release. Provides the synchronous Client::connect((email, password))? entry point, the live streaming surface (client.live().<analytic>([...]).on_event(cb)?), the bounded historical and replay preview namespaces, and the catalogue of analytics published under /analytics/.

Added

  • Synchronous thin client. kairos::Client connects over the engine's stable C ABI and delivers each emission as a typed tick row. Cloning is cheap (an Arc bump); the client is Send + Sync so multiple threads can drive subscribes through &self on the same handle.
  • Live streaming subscriptions. client.live().<analytic>([...]) .on_event(cb)? delivers each emission to the callback as a typed <Camel>Row. The Python and TypeScript bindings expose their own push-callback and pull-iterator surfaces over the same emission stream; overlapping pulls raise the typed StreamPollContention error rather than silently observing end-of-iteration.
  • Single-emission flush shortcut. Live streams no longer wait the full 25 ms flush deadline when only one emission is ready; sparse-tick streams drop from ~25 ms per emission to ~256 µs on a representative profile. The flush deadline is configurable per subscription; Duration::ZERO disables batching entirely for HFT consumers.
  • Bounded historical preview. client.historical(start, end) .<analytic>([...]).on_event(cb)? is available behind the historical-mode Cargo feature; the callback fires once per row over the bounded set. The production C-ABI path currently returns LinkError::HistoricalUnwired; in-tree testing uses Client::with_link with the replay-backed link.
  • Bounded replay preview. client.replay().<analytic>([...]) .on_event(cb)? is available behind the replay-mode Cargo feature. Same in-tree testing pathway.
  • Volatility analytic. Generalized two-variant shape: VolWindowWire::CboeVix (canonical 30-day SPX / SPXW) plus VolWindowWire::Generalized { target_days, bracket_selection, min_strikes }. CBOE-bound term-structure variants are intentionally not shipped — Kairos publishes only what it can reproduce faithfully against the published methodology.
  • Greeks, GEX, IV Skew, IV Term Structure, IV Change, OHLCVC, Implied Spot, Open Interest, Flow Recap, Stock Flow, Option Flow, Block Trade, Sweep Detector, Spread Detector, Halt Event, Historical Vol, Price Band 52W, Per-Contract Moneyness Slice, Max Pain, Put/Call Ratio, Technical Indicators, Volume Anomaly, Aggressor Sign, Option Trades, VPIN. See /analytics/ for per-analytic methodology pages.
  • Replay tick boundary validation. Dataset constructors validate every row at the load boundary (YYYYMMDD date, [0, 86_400_000) ms-of-day, finite + non-negative prices, non-negative sizes). Errors carry the offending (row_index, field, value) triple. The parquet loader also rejects null required columns with file-absolute row indexing.
  • Volatility degraded-path continuity. When either leg's implied-vol solver fails or its strike grid is missing, the analytic republishes the prior tick's value if one exists, setting REPUBLISHED_PRIOR_VALUE alongside the cause-of-degradation flag (variance-error or INSUFFICIENT_STRIKES). Both the near-leg and the next-leg paths share this contract.
  • TypeScript binding (@userfrm/kairos-thetadata). napi-rs native addon. Same surface as the Python wheel; the Client::close() async method drives deterministic teardown.
  • Python binding (kairos-thetadata). PyO3 wheel exposing Client, Credentials, live / historical / replay namespaces, and the per-analytic builders. The wheel default-enables the replay-parquet feature so from_parquet(path) is available; the transitive Apache Thrift advisory GHSA-2f9f-gq7v-9h6m is accepted under that design (see audit.toml for the review date).
  • Bindings install: in-house private preview only. npm and pip registry installs are not enabled on this release.

Security

  • Credentials zeroize end-to-end. Both bindings hold the password as Zeroizing<String> from the binding constructor through the engine Credentials::new call site; the heap buffer is wiped on drop. The bindings' Credentials.toString() / __repr__() redact both fields.
  • Live-feed TLS. Vendored from the upstream thetadatadx 11.0.1 reference implementation. See ADR-0001 in the workspace for the design choice; the decision is renewed at every upstream major or minor bump.

Known limitations

  • The production C-ABI historical path returns LinkError::HistoricalUnwired; use Client::with_link with the replay-backed link to exercise the historical surface in tests.
  • The C-ABI replay path requires a dataset-staging entry that is not yet exposed on the public surface; in-tree replay through Client::with_link is the supported pathway.

Proprietary. All rights reserved.