Skip to content

v0.0.6 — Spring 2026 audit cleanup

Choose a tag to compare

@thomaspinder thomaspinder released this 18 May 22:45
· 252 commits to main since this release
0b341ae

Cumulative cleanup release covering 14 of 16 findings from reports/audit-2026-05-18.md. Shipped as four squash-merged PRs.

What's new

Labelled DataFrames for structural results (#73, closes #72)

IRFResult.median() / .hdi(), FEVDResult.median() / .hdi(), and HistoricalDecompositionResult.median() / .hdi() now return wide DataFrames with MultiIndex(['response', 'shock']) on columns. HD additionally carries a DatetimeIndex on rows (previously the time axis was silently flattened into the row count). to_dataframe() stays as a median() passthrough until #80 decides the long-format shape.

Type-safe time-varying volatility flag (#82, closes #74)

VolatilityProcess.is_time_varying: bool replaces brittle getattr(self.volatility, 'name', None) == 'sv' string sniffing in FittedVAR.sigma and IdentifiedVAR.historical_decomposition. Constant → False, StochasticVolatility → True, both settable per-instance. Same pattern applied to SVDynamics.has_explicit_level (RandomWalk, AR1).

IdentifiedVAR.historical_decomposition short-circuits the per-t identify + invert under constant volatility — identify once, invert once, broadcast across time.

Breaking (pre-v0.1): IdentifiedVAR.impulse_response(at='all') and IdentifiedVAR.fevd(at='all') now raise ValueError for constant volatility (the per-t result was identical at every t — drop the kwarg or use at='last').

Extract MA recursion + lift time-dim guard (#77, closes #76)

New src/impulso/_ma.py with compute_ma_phi(A, horizon) — single source of truth for the structural MA recursion, shared by _ma_coefficients (posterior-batched IRF/FEVD) and SignRestriction._check_restrictions_at_horizons (single-rotation). _guard_no_time_dim lifts onto VARResultBase, parametrised by a class-level _PRIMARY_KEY.

Docstring + naming + repr cleanup (#79, closes #78)

Style sweep: double-backticks → single backticks (mkdocstrings-native); no more :meth: / :class: RST cross-refs; _MIN_OBS declared ClassVar[int]; FittedVAR.has_exog drops @computed_field; SVDynamics.build_latent_path uses pt.TensorVariable forward refs instead of Any; VARResultBase.__repr__ override deleted (Pydantic's default is already compact thanks to Field(repr=False) on idata); Constant docstrings reference L instead of stale Sigma.

Breaking (pre-v0.1): IdentifiedVAR.forecast_error_variance_decomposition removed — use IdentifiedVAR.fevd (same signature). Long name was always an alias.

Deferred for follow-up

  • #80 — Decide to_dataframe() shape (long vs wide) for VAR result classes.
  • #81 — Optional QR-based reordering for Cholesky.identify.

Both open, unassigned, no action until external triggers.