Skip to content

tsbootstrap roadmap 2025-2026 #181

Description

@astrogilda

The v0.2.0 rewrite delivered most of the 2024-2026 roadmap. Releases through v0.7.1 have since added the compiled backend, the classical and adaptive interval layers, the panel and reduce APIs, and the benchmark and supply-chain infrastructure. Status of shipped and pending work, checked against the source tree at main and the committed release history:

Delivered in v0.2.0

  • Typed functional core with one bootstrap entry point and structured results.
  • Block methods with automatic Politis-White block length; energy-normalized tapered blocks.
  • Recursive AR / ARIMA / VAR and sieve bootstraps; exogenous regressors (ARX/VARX/ARIMAX).
  • bootstrap_reduce for memory-bounded large-B calibration.
  • EnbPI prediction intervals and adaptive conformal (ACI, NexCP).
  • Narwhals DataFrame support; sktime/skbase adapters.
  • Optional numba VAR kernel (src/tsbootstrap/engines/var.py); deterministic RNG; strict typing and lint gates.

Delivered in v0.3.0 / v0.3.1

  • Optional compiled backend (backend="compiled", [accel] extra) that fuses index build, gather, and reduction into one pass, holding peak memory flat in the replicate count. Registration is in src/tsbootstrap/block/_compiled.py::register_compiled_executors.
  • Opt-in float32 simulation tensors and int32 indices for lower memory.
  • Named reducers, bootstrap_iter, and bootstrap_reduce_panel.
  • A read-only MCP server (tsbootstrap[mcp], src/tsbootstrap/mcp.py) exposing series diagnostics and a bootstrap confidence interval.
  • A published benchmark figure (benchmarks/launch_speed_memory.png) and reproduction script.
  • Refreshed tutorial notebooks for the 0.3.0 APIs (v0.3.1).

The original version of this issue described the compiled backend as "1.3x to 2.7x faster than the arch library on the four overlapping methods". That figure has been superseded twice, by the compiled-reduce re-measurement in v0.5.0 and the settled min-of-15 methodology in v0.7.0. The committed data now in benchmarks/results/vs_arch_ccx33_2026-07-11_settled.json has all sixteen cells above 1.0x, ranging from 4.75x (IID, n=2000, B=999) to 65.8x (CircularBlock, n=200, B=10000), and 4.75x to 33.1x across the larger n=2000 workloads. The large small-n multiples partly measure arch's per-replicate Python callback overhead in bs.apply, which is why benchmarks/README.md quotes the n=2000 band as the sustained figure.

Delivered in v0.4.0

  • Classical confidence intervals over a BootstrapResult: conf_int and conf_int_panel with the percentile, basic, studentized, and BCa methods (src/tsbootstrap/uq/classical.py). BCa refuses non-IID input rather than returning an interval it cannot justify; the gate is at classical.py::_acceleration_for, which raises unless the method spec is IID.
  • Wild (Wild) and block-wild (BlockWild) innovation resamplers on the residual and sieve bootstraps, so the recursion stays valid under conditional heteroskedasticity and under serial dependence a misspecified mean leaves behind.
  • A public metadata surface (metadata_for, MethodMetadata).
  • Completed citation metadata (CITATION.cff).

Delivered in v0.5.0

  • AgACI, the aggregated adaptive conformal calibrator using Bernstein Online Aggregation (Wintenberger 2017), so the ACI step size need not be chosen by hand (src/tsbootstrap/uq/adaptive.py::agaci_bounds).
  • Per-replicate Philox-4x32-10 keys derived from a root key inside the compiled reduce, with a numba-free reference implementation acting as an independent oracle (src/tsbootstrap/prng_keys.py). This changed the opt-in backend="compiled" byte stream; it is equal in distribution to the default PCG64 stream, pinned by a known-answer test, and not guaranteed stable across versions. The default numpy backend is unchanged.
  • Benchmarks updated to the compiled-reduce numbers, with corrected memory figures.

Delivered in v0.6.0 / v0.6.1

  • Frozen calibrator specs with a validated dispatch registry (src/tsbootstrap/uq/calibrators.py). Static, SlidingWindow, ACI, NexCP, and AgACI are typed, immutable, extra="forbid" specs; BaseCalibratorSpec plus register_calibrator is an open extension point, so a third-party calibrator dispatches exactly like a built-in.
  • AgACIBounds exported at the top level; the AgACI infinite-expert sentinel made scale-equivariant.
  • The executor dispatch seam and the RNG-seam contract documented, along with the decision not to split the compiled module.

Delivered in v0.7.0 / v0.7.1

  • A benchmark grid comparator that refuses cross-box millisecond comparisons, and vs-arch cells timed as a settled min-of-15 with box provenance recorded in the result JSON.
  • Load average sampled before timing, and the real CPU model read rather than assumed.
  • Supply-chain hardening: OSV lockfile scanning on pull requests and weekly, a weekly OpenSSF Scorecard run with published results, Dependabot version updates behind a 7-day cooldown, a pinned uv version, per-job release checkout permissions, and no persisted checkout credentials.
  • Mutation-testing gate fixes: mutants generated directly rather than via a stats-phase crash, the ephemeral numba cache scoped to njit-kernel mutants, and runs serialized by a concurrency group.
  • Panel API references corrected in the docs, with panel benchmark results added (v0.7.1).

Still open, near term

  • Out-of-sample forecast intervals for ARIMA and VAR. forecast_intervals in src/tsbootstrap/uq/forecast.py still raises MethodConfigError with Codes.UNSUPPORTED_MODEL_FEATURE for any model spec that is not AR. The AR-only restriction is also documented in docs/source/api_uq.rst and the forecast_intervals tutorial.
  • Python 3.14 support (Support for Python 3.14 #202, still open). pyproject.toml carries requires-python = ">=3.10,<3.14", the classifier list stops at 3.13, and the CI matrix in .github/workflows/CI.yml is ['3.10', '3.11', '3.12', '3.13'] with a comment pointing back at the pyproject cap. The cap is ours, not inherited: the core install depends only on numpy, scipy, pydantic, scikit-base, and narwhals, and statsmodels is optional, sitting in the models extra behind the ARIMA path alone. Lifting 3.14 is a change to those three places plus a matrix run, not a wait on a core dependency.

Still open, new methods (#104 / #105 / #107 all open)

  • Generalized seasonal block bootstrap (Dudek-Leskow-Paparoditis-Politis), Implement generalized block bootstrap #104.
  • Local block bootstrap for near-stationary series (Paparoditis-Politis), Implement local block bootstrap #105.
  • Frequency-domain / TFT bootstrap (Kirch-Politis), Implement frequency-domain bootstrapping #107.
  • The smooth-kernel dependent-wild bootstrap. The piecewise-constant block-wild variant shipped in v0.4.0 as BlockWild; the smooth-kernel weighting did not.
  • GARCH / volatility residual bootstrap, and Markov and distribution bootstraps.
  • SARIMA. ARIMA in src/tsbootstrap/methods.py documents seasonal orders as unsupported. This was not previously listed here.

The method registry in src/tsbootstrap/methods.py currently exports IID, MovingBlock, CircularBlock, StationaryBlock, NonOverlappingBlock, TaperedBlock, Wild, BlockWild, AR, ARIMA, VAR, ResidualBootstrap, and SieveAR. None of the method families above appears in it.

Still open, performance and scale

  • Fusing per-replicate RNG into the compiled kernel is done for part of the surface, not all of it. register_compiled_executors registers compiled values and reduce executors for IID and the four block families, plus a fused reduce for ResidualBootstrap covering the AR/VAR recursion. SieveAR and TaperedBlock still run only the numpy chunk path, so the O(B*n*d) materialization floor remains on those two.
  • An optional JAX / GPU engine for very large series-count by replicate workloads. Not built. The seams for it exist and are documented as future work in src/tsbootstrap/dispatch.py and src/tsbootstrap/prng_keys.py, which note that a JAX threefry/philox4x32 backend would register under its own backend key with no change to tsbootstrap.api, and that the reference key math exists so a GPU index stream can be made bit-identical to the CPU one.
  • Online / streaming calibration built on the reduction API. The numpy generic reduce executor is already a streaming fallback over a fixed chunk size, and ACI/AgACI adapt online over a residual buffer, but there is no incremental calibration surface that consumes a reduction stream.

Still open, ecosystem

  • An evaluation layer scoring coverage and interval width across data-generating processes. The benchmarking half of this shipped: benchmarks/ carries speed, memory, and cache-counter harnesses with committed results and a provenance-checking comparator. The evaluation half did not; there is no interval-score or empirical-coverage scoring anywhere in src/.
  • A plugin registry so third-party method specs can register executors against the open BaseMethodSpec base. Partially shipped and asymmetric. The calibrator side is done and documented as an open extension point (register_calibrator, v0.6.0). The method side has the machinery in tsbootstrap.dispatch (register_chunk_executor, register_values_executor, register_reduce_executor, register_preparer), and register_chunk_executor is re-exported from tsbootstrap.api, but none of it reaches the top-level tsbootstrap.__all__, there is no entry-point discovery, and no user-facing documentation tells a third party to use it.

Deliberately out of scope

Distributed execution (Dask / Spark / Ray), an async layer, and a string-keyed factory were considered and left out. The library is a CPU-bound, single-process toolkit. Recorded here so the decision is not relitigated.


Revised 26 August 2026. The pending section had been written before v0.5.0 through v0.7.1 shipped and no longer matched the tree. Changes: added delivered sections for v0.5.0, v0.6.0/v0.6.1, and v0.7.0/v0.7.1, none of which had been recorded; corrected the v0.3.0 compiled-backend speedup figure, which was stale by roughly an order of magnitude against the committed benchmark data; split the RNG-fusion item, which is done for ResidualBootstrap and the block families but not for SieveAR or TaperedBlock; split the evaluation-and-benchmarking item, whose benchmarking half shipped and whose evaluation half did not; split the plugin-registry item, whose calibrator half shipped in v0.6.0; added SARIMA to the open method list; and attached a file, symbol, or release to every remaining open item. Nothing was deleted: every line removed from the pending section now appears under the release that delivered it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions