validation-execution contract checks for incompatible single-run validation
combinations
a narrow wrapper-owned config/data preflight over the resolved input file
and authored column mapping
The wrapper-owned preflight checks exactly:
resolved data.path exists and is a regular file
the CSV header row can be read
the parsed header is non-empty
no parsed header cell is blank after trimming whitespace
every authored scalar entry in data.coord_to_columns exists in the header
every authored list member in data.coord_to_columns exists in the header
every authored key in media_to_channel, media_spend_to_channel,
reach_to_channel, frequency_to_channel, rf_spend_to_channel,
organic_reach_to_channel, and organic_frequency_to_channel exists in the
header
authored list-valued coord families are non-empty
authored mapping fields above are non-empty
supported media/RF family groups are complete when authored
Header matching is exact and case-sensitive. Anything outside this closed
matrix remains Meridian-owned validation.
Parameters:
run_config — A PipelineRunConfig specifying the execution config
path, output directory, run name, optional validation spec, and optional
source_config_path for metadata archival.
progress_callback — Optional callable invoked on stage lifecycle
events. The callback receives keyword arguments:
stage_name (str) — stage identifier.
event (str) — one of "started", "completed", "skipped", or
"failed".
stage_index (int) — 1-based position in the pipeline.
stage_count (int) — total number of stages.
elapsed_seconds (float) — wall-clock time (present for "completed"
and "failed" events).
message (str) — human-readable detail (present for "skipped" and
"failed" events).
Returns: A PipelineRunResult with the run directory and manifest path.
Raises:
RuntimeError if Meridian schema support is unavailable (checked at
preflight before the run directory is created).
RuntimeError if exports.export_plots is true but vl-convert-python
is not installed (also checked at preflight).
ValidationExecutionContractError if the requested single-run validation
execution path is incompatible with the authored config.
ConfigPreflightError if wrapper-owned config/data preflight fails before
run-directory creation.
PipelineRunFailure if any exception occurs after the dated run directory
already exists.
Disk locations for one completed meridian-tools run.
Attribute
Type
Description
run_dir
Path
Absolute path to the run directory.
manifest_path
Path
Absolute path to run_manifest.json.
ValidationExecutionContractError
classValidationExecutionContractError(ValueError)
Raised when the requested single-run validation execution path is incompatible
with the authored config. Current examples include direct rolling_origin
execution through run_pipeline(...) and combining
PipelineRunConfig.validation_spec with authored
model_spec.kwargs.holdout_id.
ConfigPreflightError
classConfigPreflightError(ValueError)
Raised when the wrapper-owned Phase 10 preflight fails before run-directory
creation. This covers only the closed wrapper preflight boundary, not full
Meridian model validation.
PipelineRunFailure
classPipelineRunFailure(RuntimeError)
Raised when a run fails after the dated run directory already exists.
The original underlying exception is preserved via __cause__.
Build a blocked-tail holdout mask for Meridian’s holdout_id.
Returns a 1-D boolean mask for national data and a 2-D (n_geos, n_times)
mask when geo_index is provided. The last holdout_size time periods are
marked as True (held out).
Parameters:
time_index — Strictly increasing sequence of time period identifiers.
holdout_size — Number of tail periods to hold out. Must be positive
and less than the length of time_index.
geo_index — Optional sequence of geo identifiers. If provided, the
mask is broadcast across geos.
Returns: Boolean NumPy array.
Raises:ValueError for non-monotonic indices, undersized indices, or
impossible holdout sizes.
Materialise concrete validation and final-fit run specs from one config.
For strategy: none, returns a plan with no validation runs and no
final-fit run. For blocked_tail or rolling_origin, returns one
ValidationRunSpec per split plus a final_fit_run spec that trains on
the full time axis with no holdout.
Parameters:
validation_config — A validated ValidationConfig instance.
time_index — Strictly increasing sequence of time period identifiers.
geo_index — Optional sequence of geo identifiers for geo-panel models.
One concrete validation or final-fit run derived from a split plan. Passed
to PipelineRunConfig.validation_spec to control a single pipeline
execution.
Attribute
Type
Description
mode
"validation" | "final_fit"
Run mode.
strategy
str
Validation strategy.
split_label
str
Human-readable split identifier.
holdout_source
str
How the holdout mask was produced.
generated_holdout
bool
Whether the holdout was auto-generated.
holdout_id
np.ndarray | None
Concrete holdout mask (immutable).
train_indices
tuple[int, ...]
Training time indices.
test_indices
tuple[int, ...]
Test time indices.
train_dates
tuple[str, ...]
Training date values.
test_dates
tuple[str, ...]
Test date values.
run_name_suffix
str
Suffix for the run directory name.
Methods:
to_artifact_payload() — Returns the JSON-serialisable dictionary
written to validation_spec.json.
ValidationPlan
@dataclass(frozen=True)classValidationPlan
Concrete validation runs and the separate final-fit run for one config.
Attribute
Type
Description
validation_runs
tuple[ValidationRunSpec, ...]
One spec per validation split.
final_fit_run
ValidationRunSpec | None
Full-sample final-fit spec. None for strategy: none.
meridian_tools.exports
Helpers for manifest-backed Meridian export families.
For budget.mode: relative_reference_window_total, the effective budget is
computed as value × total_spend_in_reference_window using the model’s media
and RF spend data within the start_date–end_date window.
Parameters:
model — Fitted Meridian model instance.
output_dir — Directory to write artefacts to.
optimisation_config — Optimisation settings from YAML.
exports_config — Export switches.
Returns: Dictionary mapping artefact names to file paths.
ensure_meridian_schema_support
defensure_meridian_schema_support()->Callable
Return Meridian’s schema serialiser or raise a stable runtime error.
Checks for meridian.schema.serde.meridian_serde.save_meridian. If the
import fails, raises RuntimeError with guidance to install
google-meridian[schema].
Returns: The save_meridian callable.
ensure_altair_png_support
defensure_altair_png_support()->Any
Return the Altair PNG backend or raise a stable runtime error.
Checks for vl_convert. If the import fails, raises RuntimeError with
guidance to install vl-convert-python.
Returns: The vl_convert module.
meridian_tools.diagnostics
Diagnostics extraction and export helpers for Meridian runs.
Write predictive accuracy, review summary, and bundle manifest to disk.
The bundle manifest (diagnostics_bundle.json) records the status of each
sub-export ("exported" or "disabled") along with the file name and
format. This provides a stable machine-readable contract for downstream
consumers.
When an export is disabled, any pre-existing file from a previous run at
the same path is removed to prevent stale data.
selected_geos — Not supported in current scope (raises ValueError).
selected_times — Not supported in current scope (raises ValueError).
batch_size — Batch size for Meridian analysis.
Returns: Dictionary mapping artefact names to file paths. Always
includes "diagnostics_bundle". Conditionally includes
"predictive_accuracy" and "review_summary".
Compute the pointwise log-likelihood dataset for a fitted Meridian model.
This function reconstructs the joint distribution from the posterior samples
and computes observation-level log-likelihood values. It handles both
geo-panel and national models.
The reconstruction recovers unsaved posterior parameters (e.g. geo
deviations, tau_g_excl_baseline) that Meridian does not persist to
InferenceData by default.
Parameters:
meridian_model — A fitted Meridian model with posterior samples and
a compatible posterior_sampler_callable.
Returns: An xarray Dataset with a log_likelihood variable.
Raises:ModelSelectionError if the model does not expose the required
internal reconstruction seams or lacks posterior samples.
Attach a log_likelihood group to a Meridian model’s InferenceData.
If the model’s InferenceData already has a non-empty log_likelihood
group, it is returned as-is (or the existing InferenceData is returned
for in_place=True).
Parameters:
meridian_model — A fitted Meridian model.
in_place — If True, mutates meridian_model.inference_data
directly. If False (default), returns a deep copy with the
log_likelihood group attached. The original model is never modified.
Returns: An ArviZ InferenceData with a log_likelihood group.
Raises:
ModelSelectionError with reason_code="meridian_internal_seam_incompatible"
if the Meridian version lacks the required private reconstruction methods.
ModelSelectionError with reason_code="requires_fitted_meridian_model" if
the model has no posterior samples.
ModelSelectionError with reason_code="holdout_fit_unsupported" if the
model was fitted with a holdout mask.
The reconstruction accesses three private methods on Meridian’s
posterior_sampler_callable:
_get_joint_dist_unpinned
_prepare_latents_for_reconstruction
_reconstruct_posteriors
These are Meridian-internal and may change without notice. If any method is
missing, a ModelSelectionError with
reason_code="meridian_internal_seam_incompatible" is raised instead of
crashing. See the
Meridian integration notes for
details on this coupling boundary.
meridian_tools.lifecycle
Post-run record management: loading, listing, comparing, and refreshing runs.
Module:meridian_tools.lifecycle
Functions
resolve_run_directory
defresolve_run_directory(path:str|Path)->Path
Return the absolute resolved run directory for a run path or manifest path.
If path points to a file, it must be named run_manifest.json; the
function returns its parent directory. If path is a directory, it must
contain run_manifest.json.
Parameters:
path — Path to a run directory or to run_manifest.json directly.
Returns: Absolute Path to the run directory.
Raises:LifecycleError if the path does not exist, is an unexpected
file, or the directory does not contain run_manifest.json.
load_run_record
defload_run_record(path:str|Path)->RunRecord
Load one run directory through the versioned lifecycle contract.
Resolves the run directory, parses the manifest, and resolves artefact
paths. Required artefacts (config_source, config_resolved) must be
present in the manifest and exist on disk. Manifest version 3 runs must also
include input_data_provenance. Optional artefacts (validation_spec,
diagnostics_bundle, model_selection_status) are resolved when present and
set to None when absent.
Parameters:
path — Path to a run directory or to run_manifest.json directly.
Returns: A validated RunRecord instance.
Raises:LifecycleError for missing required artefacts, malformed
manifests, artefact path traversal, or claimed-but-missing artefacts.
Discover direct child run directories under one output root.
Scans direct child directories of root for run_manifest.json files.
Returns records sorted by started_at (most recent first), with directory
name as a secondary sort key.
Parameters:
root — Directory to scan. Must be a directory, not a file.
Returns: List of RunRecord instances.
Raises:LifecycleError if root is not a directory or if any
discovered run has an invalid manifest.
Build a runtime refresh config from one stored run directory.
The execution config path points to the source run’s config.resolved.yaml.
The returned PipelineRunConfig.source_config_path preserves the source run’s
archived config.source.yaml so the refresh can re-copy the original YAML
into the new run metadata. The output directory defaults to the source run’s
parent directory (creating a sibling run). For validation runs, the
validation spec is reconstructed from the stored validation_spec.json.
Parameters:
path — Path to the run directory or manifest to refresh.
output_dir — Override the output directory (default: source parent).
run_name — Override the run name.
Returns: A PipelineRunConfig ready for run_pipeline.
Raises:LifecycleError if the source run cannot be loaded or if
authored-holdout refresh requirements are not met.
Compare two run records at the pinned metadata layer.
Loads both run records and compares run name, status, versions, validation
spec presence, diagnostics statuses, model selection availability, and
input-data provenance.
Parameters:
left — Path to the first run directory or manifest.
right — Path to the second run directory or manifest.
Returns: A pandas DataFrame with columns field, left, right,
status, and changed. Rows follow a fixed order:
Row (field)
Description
run_name
Human-readable run name.
status
Overall run status.
meridian_tools_version
meridian-tools version.
meridian_version
Google Meridian version.
has_validation_spec
Whether a validation spec is present.
has_diagnostics_bundle
Whether a diagnostics bundle is present.
predictive_accuracy_status
Status from the diagnostics bundle.
review_summary_status
Status from the diagnostics bundle.
has_model_selection_outputs
Whether LOO/WAIC outputs are present.
model_selection_reason_code
Reason code if model selection is unavailable.
input_authored_path
YAML-owned data.path string.
input_resolved_path
Absolute runtime input path.
input_mtime_utc
Input file mtime.
input_sha256
Input file SHA-256 digest.
input_size_bytes
Input file size in bytes.
input_row_count
Input row count.
input_column_count
Input column count.
input_ordered_columns
Input CSV column order.
For provenance rows, status is "legacy_unknown" and changed is None
when either run predates manifest version 3 and therefore has no stored
provenance payload.
Raises:LifecycleError if either run cannot be loaded or if
diagnostics or model selection artefacts are malformed.
Classes
RunRecord
@dataclass(frozen=True)classRunRecord
Resolved lifecycle view over one on-disk run directory.
Attribute
Type
Description
run_dir
Path
Absolute path to the run directory.
manifest_path
Path
Absolute path to run_manifest.json.
manifest
RunManifest
Parsed manifest with stages, timestamps, and versions.
config_source_path
Path
Absolute path to config.source.yaml. Always present.
config_resolved_path
Path
Absolute path to config.resolved.yaml. Always present.
input_data_provenance_path
Path | None
Path to input_data_provenance.json. Required for manifest version 3 runs, otherwise None.
validation_spec_path
Path | None
Path to validation_spec.json, or None if absent.
diagnostics_bundle_path
Path | None
Path to diagnostics_bundle.json, or None if absent.
model_selection_status_path
Path | None
Path to model_selection_status.json, or None if absent.
Required attributes (config_source_path, config_resolved_path) are
always present. input_data_provenance_path is present for manifest version
3 runs. Other optional attributes are None when the corresponding artefact
was not produced by the run or is absent from the manifest.
Example:
frommeridian_tools.lifecycleimportload_run_recordrecord=load_run_record("runs/my-project_blocked_tail_20260402_073500")# Required — always availableprint(record.config_source_path)print(record.config_resolved_path)# Optional — may be Noneifrecord.diagnostics_bundle_path:print(f"Diagnostics: {record.diagnostics_bundle_path}")ifrecord.validation_spec_path:print(f"Validation spec: {record.validation_spec_path}")
LifecycleError
classLifecycleError(RuntimeError)
Raised when a run directory cannot be loaded through the lifecycle
contract. All lifecycle functions raise this exception type instead of
generic ValueError or RuntimeError.
meridian_tools.artifacts
Manifest and JSON helpers for run artefact management.
Module:meridian_tools.artifacts
Functions
write_json
defwrite_json(path:str|Path,payload:Any)->None
Write a JSON-serialisable payload to disk with UTF-8 encoding and
2-space indentation. Creates parent directories if they do not exist.
Convert artefact paths to relative paths against run_dir so the manifest
stores portable references.
Parameters:
run_dir — The run directory root.
artifacts — Mapping of artefact names to file paths.
Returns: Dictionary mapping artefact names to relative path strings.
timestamp_utc
deftimestamp_utc()->str
Return the current time as a UTC ISO-8601 string with second precision.
Classes
RunManifest
@dataclassclassRunManifest
Machine-readable summary of one meridian-tools run.
Attribute
Type
Default
Description
run_name
str
required
Human-readable run name.
config_path
Path
required
Path to the authored YAML config file.
output_dir
Path
required
Path to the run directory.
started_at
str
required
UTC ISO-8601 start timestamp.
manifest_version
int
CURRENT_MANIFEST_VERSION
Schema version (0, 1, 2, or 3).
status
str
"running"
Overall run status: "running", "completed", or "failed".
finished_at
str | None
None
UTC ISO-8601 finish timestamp. None while the run is in progress.
meridian_tools_version
str
__version__
Version of meridian-tools.
meridian_version
str | None
None
Version of Google Meridian.
artifacts
dict[str, str]
{}
Top-level artefact index. Key artefacts from stages are promoted here.
stages
list[StageRecord]
[]
Ordered list of stage records (completed, skipped, and failed).
Class methods:
from_dict(payload: Mapping[str, Any]) -> RunManifest — Deserialise
from a JSON-parsed dictionary. Supports manifest versions 0, 1, 2, and 3 with
default values for missing fields in older versions. Raises ValueError
for unsupported versions or missing required fields.
Instance methods:
to_dict() -> dict[str, Any] — Serialise to a JSON-compatible
dictionary.
StageRecord
@dataclassclassStageRecord
One pipeline stage entry in the run manifest.
Attribute
Type
Default
Description
name
str
required
Stage identifier (for example, "00_run_metadata").
status
str
"pending"
Stage status: "pending", "running", "completed", "skipped", or "failed".
started_at
str | None
None
UTC ISO-8601 start timestamp.
finished_at
str | None
None
UTC ISO-8601 finish timestamp.
elapsed_seconds
float | None
None
Wall-clock seconds for stage execution.
message
str | None
None
Human-readable message (skip reason or error detail).
artifacts
dict[str, str]
{}
Map of artefact names to relative paths. Empty for skipped stages.
Class methods:
from_dict(payload: Mapping[str, Any]) -> StageRecord — Deserialise
from a JSON-parsed dictionary. Raises ValueError if name is missing.
InputDataProvenance
@dataclass(frozen=True)classInputDataProvenance
Pinned input-data provenance payload used by manifest version 3 runs.
Attribute
Type
Default
Description
authored_path
str
required
Exact data.path string from the source YAML.
resolved_path
str
required
Absolute runtime path used for input loading.
sha256
str
required
SHA-256 digest of the resolved input file.
size_bytes
int
required
Input file size in bytes.
mtime_utc
str
required
Input file modification time in UTC ISO-8601 format.
row_count
int
required
Number of CSV data rows.
column_count
int
required
Number of CSV columns.
ordered_columns
tuple[str, ...]
required
CSV header order.
provenance_version
int
INPUT_DATA_PROVENANCE_VERSION
Payload schema version.
Class methods:
from_dict(payload: Mapping[str, Any]) -> InputDataProvenance —
Validates the exact pinned Phase 09 key set and types.
Instance methods:
to_dict() -> dict[str, Any] — Serialise to the exact JSON payload
written into input_data_provenance.json.
These artefact entries are validated at run completion time by the runner.
New runs must produce all four to complete successfully.
The lifecycle loader enforces config_source and config_resolved as
required for all supported manifests. It also enforces
input_data_provenance for manifest version 3 runs. diagnostics_bundle
remains optional, so older or partial runs can still be loaded without it.