update, repeat — plus what
goes wrong when you skip a step.
Which methods are online
IS_ONLINE is a ClassVar — class metadata rather than a config field,
so you can ask before you build anything, and it never shows up in a
constructor or in model_json_schema().
update method. It lives on the fitted
object that calibrate returns, and delegates to an _update hook,
which the offline fitted classes leave as the inherited no-op and the
four online ones override. Calling it on an offline method is harmless,
which means a generic pipeline can call update unconditionally without
branching on the method type.
The loop
calibrate_cv returns a fitted object, and that object is what learns:
each update mutates it in place and returns None.
truthmust have the forecast’s shapeupdatetakes(prediction, truth)with both shaped(n_series, 1, horizon)— the same 3-DForecastshapepredictreturns, not the flat(n_series,)slice you took out of your panel. Thepanel[:, t : t + 1][:, None, :]above is that reshape: one series axis, one sample, one horizon step.
Snapshots Becauseupdatemutates the fitted object, keep a copy if you need the state from before a stream — say, to replay a different stream from the same starting point:snapshot = fitted.model_copy(deep=True). The copy shares nothing with the original, so later updates never reach it.
What updating buys
Run the same stream several ways: three online methods, one online method that is calibrated but never fed, and split conformal for reference.alpha_t the calibration
pass happened to leave behind — 0.016 here, not the 0.1 that was asked
for — and then holds that forever. The result is a 100% covering band,
40% wider than split conformal, aimed at a confidence level nobody
chose.
So an online method that is not fed is worse than an offline one: it is
a fixed interval at an arbitrary level, carrying the overhead of a
controller that never runs. If your pipeline cannot deliver truths back,
pick an offline method deliberately rather than inheriting one by
accident.

Online state survives calibration
calibrate_cv does not merely collect residuals for an online method —
it rolls the method’s state forward through every calibration window. By
the time the stream starts, alpha_t has already moved.
n_observations after the 48-month stream above reads 96
rather than 48, and why an online method’s diagnostics are cumulative
across both phases.
Updating out of order
update assumes the truth you hand it is the one that followed the
prediction you hand it. Nothing checks that — the arrays have no
timestamps — so an out-of-order or duplicated update corrupts the state
silently.
Three rules for a production loop
- Update once per observation. Replaying the same truth twice tells the controller it missed (or hit) twice.
- Update in time order. NexCP weights by position and SPCI regresses on a residual sequence; both read the order as time.
- Pair the truth with the prediction that preceded it, not with the newest forecast. Passing
prediction.pointstraight through, as above, makes this automatic.
Next
- ACI — the controller, in detail.
- AgACI — several controllers, aggregated.
- Diagnostics —
rolling_coverageand the per-method state helpers, includingmethod_stateused above.

