Migration Guide
This guide covers migration between the released v1 API and the normative v2 release contract, as well as the earlier 0.x-to-v1 transition. The API reference links each machine-readable contract. Experimental and provisional extensions do not receive the same compatibility guarantee.
Migrating from 1.x to 2.0
Section titled “Migrating from 1.x to 2.0”v2 corrects the scientific model used by the built-in two-loop expected value
of sample information (EVSI) calculation. The correction changes numerical
behaviour, not only implementation details, so it is a major-version change.
The immutable v1 contract remains in specs/v1/; the v2 contract is in
specs/v2/.
Signature boundary
Section titled “Signature boundary”The v1 signature ended with a positional-or-keyword seed and did not expose study-model callbacks:
evsi( model_func, psa_prior, trial_design, population=None, discount_rate=None, time_horizon=None, method="two_loop", n_outer_loops=100, n_inner_loops=1000, metamodel="linear", seed=None,)In v2, seed becomes keyword-only, and the paired custom-model callbacks are
also keyword-only:
evsi( model_func, psa_prior, trial_design, population=None, discount_rate=None, time_horizon=None, method="two_loop", n_outer_loops=100, n_inner_loops=1000, metamodel="linear", *, seed=None, trial_simulator=None, posterior_sampler=None,)Pass seed by name before upgrading:
value = evsi( model, prior, design, method="two_loop", n_outer_loops=500, n_inner_loops=2_000, seed=20260724,)Do not compare a v1 and v2 result as if they were two implementations of the same estimator. Preserve the v1 environment, input artifact, seed, result, and version metadata when an analysis requires an audit trail.
Behaviour boundary
Section titled “Behaviour boundary”| Concern | v1 | v2 |
|---|---|---|
| Built-in prior | empirical PSA rows for outer truths; separate marginal normal updates | one fitted joint multivariate-normal prior throughout |
| Current decision | empirical PSA sample | draws or integration from the fitted joint prior |
| Posterior | observed arm means updated independently | exact joint Gaussian conditioning for every correlated stochastic parameter |
| Fixed outcome SD | part of the parameter sample | validated as finite, constant, and positive; excluded from stochastic covariance |
| Inner-loop meaning | repeated posterior/model calculations with v1 sample-size behaviour | exactly n_inner_loops joint posterior draws per outer data set |
| Negative simulation estimate | clipped to zero by the public calculation | returned untruncated so simulation error remains visible |
| Custom study model | unavailable | paired keyword-only simulation and posterior callbacks |
| Unseeded RNG | NumPy process-global stream | fresh local numpy.random.Generator |
| Seeded RNG | local generator, but seed could be positional | local generator with keyword-only unsigned 64-bit seed |
The coherent built-in model requires:
- finite PSA rows from which a joint multivariate-normal prior can be fitted;
- one unique
mean_<arm>stochastic parameter for each study arm; - a common
sd_outcomethat is finite, strictly positive, and constant across the PSA rows; - positive, non-Boolean integer outer- and inner-loop counts; and
- a covariance matrix that can be conditioned safely.
Inputs that do not define that model raise InputError or NumericalError.
Raw NumPy linear-algebra exceptions are not part of the public contract.
Analytical normal–normal EVSI
Section titled “Analytical normal–normal EVSI”Use normal_normal_two_arm_evsi when the decision problem has one uncertain
incremental effect, an equal-allocation two-arm normal study with known common
outcome variance, and linear incremental net benefit:
from voiage import normal_normal_two_arm_evsi
value = normal_normal_two_arm_evsi( prior_mean=0.06, prior_standard_deviation=0.03, outcome_standard_deviation=1.0, total_sample_size=200, net_benefit_slope=50_000.0, net_benefit_intercept=-3_000.0,)This function is analytical, Rust-owned, deterministic, and uses no random
number generator. All arguments are keyword-only and total_sample_size is a
positive even integer.
Custom two-loop studies
Section titled “Custom two-loop studies”If the fitted-normal model is not appropriate, provide both callbacks:
value = evsi( model, prior, design, method="two_loop", seed=20260724, trial_simulator=simulate_trial, posterior_sampler=sample_joint_posterior,)trial_simulator(true_joint_parameters, trial_design, rng) returns one
simulated data set. posterior_sampler(prior, trial_data, trial_design, n_draws, rng) returns exactly n_draws complete, joint posterior rows in a
ParameterSet. Both callbacks need to represent the same prior, likelihood,
and posterior model.
The regression, efficient, efficient-regression, and moment-based EVSI estimators are provisional in v2. Treat them as compatibility tools rather than substitutes for a declared study model.
Binding migration
Section titled “Binding migration”Python, R, and Julia packages that expose EVSI need to identify the contract version they implement. A binding remains on the v1 contract until its signature, local-RNG behaviour, model semantics, errors, fixtures, and documentation conform to v2. Merely linking a newer shared library does not establish v2 conformance.
Migrating from 0.x to 1.0
Section titled “Migrating from 0.x to 1.0”Runtime and installation
Section titled “Runtime and installation”v1 supports Python 3.12, 3.13, and 3.14. Install a platform wheel or build with the documented Rust toolchain. The Rust core is required for stable numerical operations: v1 does not silently fall back to an independent Python numerical implementation.
If the native module or a required Rust capability is unavailable, stable
operations raise BackendNotAvailableError. Treat that as an installation or
capability error; do not catch it and substitute an unverified 0.x algorithm.
Stable imports and typed inputs
Section titled “Stable imports and typed inputs”Prefer the stable top-level symbols:
from voiage import DecisionAnalysis, ParameterSet, evpi, evppi, evsiReplace raw dictionary parameter samples passed to evppi with a
ParameterSet. The temporary dictionary bridge emits FutureWarning with
diagnostic code deprecated_raw_dict_parameter_samples:
from voiage import ParameterSet, evppi
parameters = ParameterSet.from_numpy_or_dict( {"treatment_effect": treatment_effect_samples})result = evppi(net_benefit, parameters, ["treatment_effect"])Stable results and errors are Rust-owned versioned contracts. Python may expose NumPy or xarray views for convenience, but callers should not depend on private Python implementation modules or experimental result shapes.
Removed and non-stable surfaces
Section titled “Removed and non-stable surfaces”Go, TypeScript, .NET, WASM, and the duplicate standalone Rust binding are not retained v1 bindings. The supported repository-owned surfaces are Rust, Python/PyO3, R, and Julia. Mojo remains an external upstream interoperation boundary until an approved toolchain and distribution contract exist.
Web, widget, accelerator, distributed, and research methods are optional or experimental. Install their named extras deliberately and consult each page’s maturity label before relying on it in a production compatibility contract.
Rollback and support
Section titled “Rollback and support”Test migration in a clean environment and retain the prior environment lock, input fixtures, random seeds, and result checksums until representative v1 analyses pass. Do not overwrite or move a signed release tag. If v1 exposes a material regression, preserve the failing evidence, open an issue with the smallest non-confidential reproducer, and pin the last known-good published version while a new patch release proceeds through the full release workflow.
Equity-information VOI
Section titled “Equity-information VOI”The new value_of_equity_information method is fixture-backed and measures
the value of resolving uncertain equity weights across policy-relevant
subgroups. It is intentionally separate from the experimental
value_of_distributional_equity method, which measures subgroup tailoring.
The new method reports baseline and resolved social-welfare decisions, scenario probabilities, subgroup expected net benefits, and a sample-allocation diagnostic. Cross-language parity and licensed open-data attribution remain promotion gates; no stable claim is made yet.
value_of_ambiguity_distribution_shift is also fixture-backed. It uses
source-sample reweightings to model plausible distribution shift and reports a
radius-penalized robust strategy, scenario regret, and drift sensitivity.
value_of_adaptive_learning_bandit adds fixture-backed sequential allocation
with UCB, Thompson, and epsilon-greedy policies. It reports exploration cost,
regret, switching, sampling burden, and stopping diagnostics; open-data
attribution and cross-language parity remain stable-promotion gates.
value_of_federated_privacy_preserving adds site-local summary aggregation
without centralizing individual-level records. It reports privacy-budget loss,
secure-aggregation error, disclosure-risk metadata, and site contribution
values, with synthetic-summary fallback when individual access is blocked.
Licensed multi-site data, cross-language parity, and stable promotion remain
explicit gates.
value_of_ai_assisted_evidence_triage adds fixture-backed, human-in-the-loop
VOI for screening and extraction support. It reports sensitivity, specificity,
decision-impact-weighted false exclusion/inclusion burden, reviewer time saved,
audit value, extraction error, model drift, and automation economics. Licensed
evidence-corpus validation, cross-language parity, and stable promotion remain
explicit gates.
Interoperability and standardization VOI
Section titled “Interoperability and standardization VOI”The fixture-backed value_of_interoperability_standardization method is
available for harmonization, common-data-model reuse, and transformation-error
analysis. It reports standardization cost separately and should remain
experimental/fixture-backed until licensed cross-site evidence and parity
review are complete.
Regulatory and market-access VOI
Section titled “Regulatory and market-access VOI”The fixture-backed value_of_regulatory_market_access method models approval,
reimbursement, label, pricing, coverage, delay, and evidence-package economics.
It remains fixture-backed until calibrated regulatory and payer evidence plus
cross-language parity are available.
Replication and reproducibility VOI
Section titled “Replication and reproducibility VOI”The fixture-backed value_of_replication_reproducibility method is available
through Python and the calculate-replication-reproducibility CLI command. It
does not change existing method defaults and remains subject to explicit data
provenance and parity gates.
Evidence obsolescence and refresh VOI
Section titled “Evidence obsolescence and refresh VOI”The fixture-backed value_of_evidence_obsolescence_refresh method is available
through Python and the calculate-evidence-obsolescence-refresh CLI command.
It models refresh cadence without changing existing method defaults.
Strategic behavior and game-theoretic VOI
Section titled “Strategic behavior and game-theoretic VOI”The fixture-backed value_of_strategic_behavior method is available through
Python and the calculate-strategic-behavior CLI command. It remains subject
to calibrated-game-data and parity gates.