Manifest schema reference — The run_manifest.json file is the source of truth for every meridian-tools run. It lives at the root of the run directory and records identity, timing, versions, overall status, top-level artefact index, and per-stage records.
Output schema reference — This page documents the complete run directory layout produced by meridian-tools. Every successful pipeline run creates a timestamped directory containing the artefacts described below.
Validation spec schema reference — The validation_spec.json artefact is written to 10_validation/ for every validation-aware pipeline run. It records the concrete validation provenance for that specific run, including the holdout strategy, split geometry, and date windows. Current runs write validation-spec version 2, which also binds the source coordinate fingerprints and the execution prefix used by the split.
Subsections of Reference
CLI reference
meridian-tools provides a command-line interface with two subcommands: run
and demo.
Global usage
meridian-tools <subcommand> [options]
meridian-tools run
Execute a meridian-tools pipeline run from an authored YAML config.
meridian-tools run --config <path> [--output-dir <dir>][--run-name <name>][--traceback]
Arguments
Argument
Required
Default
Description
--config
Yes
—
Path to the meridian-tools YAML configuration file.
--output-dir
No
runs
Directory where dated run folders will be created.
--run-name
No
project.name from YAML
Optional run name override.
--traceback
No
false
Show the full Python traceback on failure.
Examples
# Basic runmeridian-tools run --config project.yml
# Custom output directorymeridian-tools run --config project.yml --output-dir output/model_runs
# Named run with traceback on failuremeridian-tools run --config project.yml --run-name client-q1-review --traceback
Exit codes
Code
Meaning
0
Pipeline completed successfully.
1
Pipeline failed. Error details are printed to stderr. Use --traceback for the full stack trace.
Failure reporting
The CLI distinguishes five broad failure classes:
config loading or Pydantic validation failures before wrapper preflight
dependency preflight failures before run-directory creation
validation-execution contract failures before run-directory creation
wrapper-owned ConfigPreflightError failures before run-directory creation
PipelineRunFailure after the dated run directory already exists
Dependency preflight covers google-meridian[schema] support and optional
plot-export support. Validation-execution contract failures cover incompatible
single-run validation requests such as direct rolling_origin execution.
Wrapper preflight covers only the closed config/data matrix documented in the
configuration guide.
For PipelineRunFailure, the CLI prints the concrete failed run directory,
manifest path, and stage name when available so the partial run can be
inspected immediately. --traceback still shows the original underlying
exception because it is preserved through __cause__.
Validation strategy restrictions
The CLI executes a single pipeline run. Configs with
validation.strategy: rolling_origin cannot be run directly from the CLI
because they require multiple sequential runs. Use the
Python API for rolling-origin workflows.
Configs with strategy: none or strategy: blocked_tail work directly from
the CLI.
meridian-tools demo
Run one of the bundled reference demos or list available demos.
Bundled demo name to execute. One of: timeseries, geo_panel.
--list
No
false
List supported demos and exit. Cannot combine with a demo name.
--output-dir
No
runs/demos/ (source checkout) or ./runs/demos/ (installed)
Override the output root directory.
--run-name
No
None (uses project.name from the demo config)
Optional run name override.
--traceback
No
false
Show the full Python traceback on failure.
Examples
# List available demosmeridian-tools demo --list
# Run the timeseries demomeridian-tools demo timeseries
# Run with a custom output directorymeridian-tools demo geo_panel --output-dir sandbox/demo-output
# Run with a custom namemeridian-tools demo timeseries --run-name demo-review-q2
Available demos
Name
Description
timeseries
National timeseries demo using bundled reference data.
geo_panel
Geo-panel demo using bundled reference data.
Both demos exercise the full staged pipeline including response curves and
optimisation.
Lightweight import
The CLI is designed for fast startup. Running meridian-tools --help or
meridian-tools demo --list does not import TensorFlow, NumPy, Meridian,
or ArviZ. Heavy imports are deferred until pipeline execution begins.
Entrypoints
The primary CLI entrypoint is the console script registered in
pyproject.toml:
Keyword arguments forwarded directly to Meridian ModelSpec(**kwargs).
priors
PriorsConfig | null
null
YAML-driven media prior configuration.
Supported kwargs keys include any argument accepted by Meridian’s ModelSpec
constructor: max_lag, media_prior_type, holdout_id, etc. If holdout_id
is present, the run is treated as an authored-holdout validation run.
Array-valued keys (holdout_id, control_population_scaling_id,
non_media_population_scaling_id, rf_roi_calibration_period,
roi_calibration_period) must be rectangular YAML lists of booleans. Scalars,
ragged lists, string booleans such as "true", and numeric stand-ins such as
1/0 are rejected by the wrapper before Meridian model construction. Valid
values are converted to NumPy arrays at runtime.
Authored holdout_id arrays are shape-checked after input data loading:
national data expects (n_times,), and geo data expects (n_geos, n_times).
Authored holdout_id cannot be combined with a runtime
PipelineRunConfig.validation_spec.
Other wrapper-owned array kwargs are also rank- and shape-checked before model
construction: roi_calibration_period expects
(n_media_times, n_media_channels), rf_roi_calibration_period expects
(n_media_times, n_rf_channels), control_population_scaling_id expects
(n_controls,), and non_media_population_scaling_id expects
(n_non_media_channels,). These kwargs require their corresponding
data.coord_to_columns families to be authored.
model_spec.priors
Optional. If omitted, Meridian’s default PriorDistribution is used.
This focused YAML surface supports media prior parameters roi_m, mroi_m,
and alpha_m.
Each prior parameter can be specified in scalar form:
strategy: rolling_origin requires initial_train_size and test_size, rejects holdout_size.
holdout_size without an explicit strategy is rejected (legacy shorthand removed).
Rolling-origin parameters without strategy: rolling_origin are rejected.
exports
Field
Type
Default
Description
use_kpi
bool
false
Use KPI-based metrics in Meridian analysis surfaces.
batch_size
PositiveInt
1000
Batch size for Meridian Analyzer computations.
export_predictive_accuracy
bool
true
Write predictive_accuracy.csv.
export_review_summary
bool
true
Write review_summary.json.
export_model_selection
bool
true
Write LOO/WAIC outputs (when compatible).
export_plots
bool
true
Write PNG plot artefacts in each stage.
response_curves
Optional section. If omitted or null, the response curves stage is skipped.
Field
Type
Default
Constraint
Description
spend_multipliers
list[float]
required
Non-empty, all >=0
Spend multiplier grid for response curve computation.
use_posterior
bool
true
—
Use posterior (vs prior) for response curves.
by_reach
bool
true
—
Compute reach-based response curves.
use_optimal_frequency
bool
false
—
Use optimal frequency in computation.
confidence_level
float
0.9
0 < x < 1
Confidence level for credible intervals.
optimisation
Optional section. If omitted or null, the optimisation stage is skipped.
Field
Type
Default
Constraint
Description
start_date
str
required
ISO YYYY-MM-DD
Start of the optimisation window.
end_date
str
required
ISO YYYY-MM-DD, >= start_date
End of the optimisation window.
budget
OptimisationBudgetConfig
required
—
Budget specification (see below).
use_posterior
bool
true
—
Use posterior (vs prior) for optimisation.
use_optimal_frequency
bool
true
—
Use optimal frequency in optimisation.
confidence_level
float
0.9
0 < x < 1
Confidence level for credible intervals.
optimisation.budget
Field
Type
Default
Constraint
Description
mode
"fixed_total" | "relative_reference_window_total"
required
—
Budget mode.
value
PositiveFloat
required
>0
Budget value. Absolute for fixed_total, multiplier for relative_reference_window_total.
When mode: relative_reference_window_total, the effective budget is
value × total_spend_in_reference_window. The reference window is defined by
start_date and end_date.
Manifest schema reference
The run_manifest.json file is the source of truth for every
meridian-tools run. It lives at the root of the run directory and records
identity, timing, versions, overall status, top-level artefact index, and
per-stage records.
Current version
The current manifest version is 4. Versions 0, 1, 2, and 3 are supported
for backward compatibility when loading older run directories.
Top-level fields
Field
Type
Description
manifest_version
int
Schema version (0, 1, 2, 3, or 4).
run_name
str
Human-readable run name.
config_path
str
Path to the source YAML used for this run. For refresh runs this points to the source run’s archived config.source.yaml.
output_dir
str
Path to the run directory.
started_at
str
UTC ISO-8601 timestamp when the run began.
status
str
Overall run status: "running", "completed", or "failed".
finished_at
str | null
UTC ISO-8601 timestamp when the run finished. null while running.
meridian_tools_version
str
Version of meridian-tools that produced the run.
meridian_version
str | null
Version of Google Meridian used. null if not yet recorded.
artifacts
dict[str, str]
Top-level artefact index. Key artefacts from stages are promoted here for quick lookup.
stages
list[StageRecord]
Ordered list of pipeline stage records (including skipped and failed stages).
Top-level artifacts index
The runner promotes key artefacts into the top-level artifacts dictionary
after each stage completes. Promoted artefact names include:
This index provides flat access to important artefacts without walking the
stages array.
StageRecord fields
Each entry in the stages array represents one pipeline stage. Stages can
have any of four statuses: "running", "completed", "skipped", or
"failed".
Field
Type
Description
name
str
Stage identifier (for example, "00_run_metadata", "20_model_fit").
status
str
Stage status: "running", "completed", "skipped", or "failed".
started_at
str | null
UTC ISO-8601 timestamp when the stage began.
finished_at
str | null
UTC ISO-8601 timestamp when the stage finished.
elapsed_seconds
float | null
Wall-clock seconds for stage execution.
message
str | null
Human-readable message. Present for skipped stages (reason) and failed stages (error).
artifacts
dict[str, str]
Map of artefact names to relative file paths. Empty for skipped stages.
Artefact path convention
All artefact paths in manifests written by run_pipeline are relative to the
run directory and must resolve to existing regular files inside that
directory. Producers reject absolute paths, lexical .. components, paths that
resolve outside the run directory, missing paths, directories, and special
files. Internal symlinks are accepted only when they resolve to regular files
inside the run directory.
This makes run directories portable across machines and file systems. When you
load a run record through load_run_record, the lifecycle layer resolves
relative paths to absolute paths against the run directory.
All seven stages are always recorded in execution order. Stages that do not
apply to a given run are recorded with status: "skipped".
Stage name
Number
Skippable
Description
00_run_metadata
00
No
Config archival and input-data provenance capture.
10_validation
10
Yes
Validation spec (skipped when no validation applies).
20_model_fit
20
No
Meridian model fitting.
30_model_assessment
30
No
Diagnostics, model selection.
40_decomposition
40
No
Media decomposition metrics.
60_response_curves
60
Yes
Response curves (skipped when the config section is absent).
70_optimisation
70
Yes
Budget optimisation (skipped when the config section is absent).
The numbering gap at 50 is intentional, reserving space for future stages.
Required artefacts
The lifecycle loader requires the following top-level artefacts to be present
in the manifest for a run to be loadable:
config_source (promoted from 00_run_metadata)
config_resolved (promoted from 00_run_metadata)
input_data_provenance (promoted from 00_run_metadata) for manifest
version 3 and 4 runs
These are enforced by _require_manifest_artifact in load_run_record. If a
required entry is missing, a LifecycleError is raised.
At run completion time, new manifest version 4 runs also validate the full
REQUIRED_MANIFEST_ARTIFACTS set: config_source, config_resolved,
input_data_provenance, and diagnostics_bundle. The lifecycle loader still
treats diagnostics_bundle as optional so older or partial runs can be loaded
without it; if it is absent, RunRecord.diagnostics_bundle_path is None.
Input-data provenance payload
Manifest version 3 introduced 00_run_metadata/input_data_provenance.json.
This file records the pinned Phase 09 input-data contract:
provenance_version
authored_path
resolved_path
sha256
size_bytes
mtime_utc
row_count
column_count
ordered_columns
The lifecycle compare surface uses these fields to distinguish real dataset
changes from older runs whose manifests predate provenance capture.
Example manifest
{"manifest_version":4,"run_name":"my-project_blocked_tail","config_path":"/workspace/configs/project.yml","output_dir":"/workspace/runs/my-project_blocked_tail_20260402_073500","started_at":"2026-04-02T07:35:00+00:00","status":"completed","finished_at":"2026-04-02T07:42:15+00:00","meridian_tools_version":"0.4.0","meridian_version":"1.5.3","artifacts":{"config_source":"00_run_metadata/config.source.yaml","config_resolved":"00_run_metadata/config.resolved.yaml","input_data_provenance":"00_run_metadata/input_data_provenance.json","validation_spec":"10_validation/validation_spec.json","meridian_model":"20_model_fit/meridian_model.binpb","diagnostics_bundle":"30_model_assessment/diagnostics_bundle.json","model_results_summary":"30_model_assessment/model_results_summary.html","summary_metrics_csv":"40_decomposition/summary_metrics.csv","summary_metrics_nc":"40_decomposition/summary_metrics.nc"},"stages":[{"name":"00_run_metadata","status":"completed","started_at":"2026-04-02T07:35:00+00:00","finished_at":"2026-04-02T07:35:01+00:00","elapsed_seconds":0.5,"message":null,"artifacts":{"config_source":"00_run_metadata/config.source.yaml","config_resolved":"00_run_metadata/config.resolved.yaml","input_data_provenance":"00_run_metadata/input_data_provenance.json"}},{"name":"10_validation","status":"completed","started_at":"2026-04-02T07:35:01+00:00","finished_at":"2026-04-02T07:35:01+00:00","elapsed_seconds":0.1,"message":null,"artifacts":{"validation_spec":"10_validation/validation_spec.json"}},{"name":"20_model_fit","status":"completed","started_at":"2026-04-02T07:35:01+00:00","finished_at":"2026-04-02T07:40:30+00:00","elapsed_seconds":329.0,"message":null,"artifacts":{"meridian_model":"20_model_fit/meridian_model.binpb","fit_metadata":"20_model_fit/fit_metadata.json","prior_distributions":"20_model_fit/prior_distributions.json"}},{"name":"30_model_assessment","status":"completed","started_at":"2026-04-02T07:40:30+00:00","finished_at":"2026-04-02T07:41:00+00:00","elapsed_seconds":30.1,"message":null,"artifacts":{"diagnostics_bundle":"30_model_assessment/diagnostics_bundle.json","review_summary":"30_model_assessment/review_summary.json","model_results_summary":"30_model_assessment/model_results_summary.html","model_selection_status":"30_model_assessment/model_selection_status.json"}},{"name":"40_decomposition","status":"completed","started_at":"2026-04-02T07:41:00+00:00","finished_at":"2026-04-02T07:42:00+00:00","elapsed_seconds":60.0,"message":null,"artifacts":{"summary_metrics_nc":"40_decomposition/summary_metrics.nc","summary_metrics_csv":"40_decomposition/summary_metrics.csv"}},{"name":"60_response_curves","status":"skipped","started_at":"2026-04-02T07:42:00+00:00","finished_at":"2026-04-02T07:42:00+00:00","elapsed_seconds":0.0,"message":"No `response_curves` section was authored in the YAML config.","artifacts":{}},{"name":"70_optimisation","status":"skipped","started_at":"2026-04-02T07:42:00+00:00","finished_at":"2026-04-02T07:42:00+00:00","elapsed_seconds":0.0,"message":"No `optimisation` section was authored in the YAML config.","artifacts":{}}]}
Version history
Version 4 (current)
Added fail-closed artefact integrity checks for completed runs. New runs must
promote and validate config_source, config_resolved,
input_data_provenance, and diagnostics_bundle before completion. Manifest
artefact paths must resolve to regular files inside the run directory.
Version 3
Added input_data_provenance.json and made provenance available to lifecycle
loading and compare surfaces.
Version 2
Added export_plots support, top-level artifacts index, status field,
config_path, output_dir, and per-stage status, elapsed_seconds, and
message fields.
Version 1
Added meridian_version field and response_curves / optimisation stages.
Version 0
Initial manifest schema with core stages and artefact tracking.
All four versions are supported by RunManifest.from_dict. Missing fields in
older versions are filled with defaults.
Output schema reference
This page documents the complete run directory layout produced by
meridian-tools. Every successful pipeline run creates a timestamped
directory containing the artefacts described below.
Run directory structure
<run_name>_<YYYYMMDD_HHMMSS>/
│
├── run_manifest.json # Source of truth for the run
│
├── 00_run_metadata/
│ ├── config.source.yaml # Verbatim copy of the authored YAML
│ ├── config.resolved.yaml # YAML after path resolution
│ └── input_data_provenance.json # Pinned source/resolution/hash metadata
│
├── 10_validation/ # Only for validation-aware runs
│ └── validation_spec.json # Validation provenance record
│
├── 20_model_fit/
│ ├── meridian_model.binpb # Serialised Meridian model
│ └── fit_metadata.json # Fit settings and Meridian version
│
├── 30_model_assessment/
│ ├── diagnostics_bundle.json # Diagnostics export manifest
│ ├── predictive_accuracy.csv # Per-observation accuracy metrics
│ ├── review_summary.json # Meridian review battery results
│ ├── model_results_summary.html # Meridian HTML summary report
│ ├── plots/ # When export_plots: true
│ │ ├── model_fit.png
│ │ └── rhat_boxplot.png
│ │
│ │ # Model selection outputs (compatible runs):
│ ├── loo_summary.json # LOO summary statistics
│ ├── waic_summary.json # WAIC summary statistics
│ ├── loo_pointwise.csv # Per-observation LOO + Pareto k
│ ├── waic_pointwise.csv # Per-observation WAIC
│ ├── model_comparison.csv # Ranked comparison table
│ └── model_selection_warnings.json # Warning details, when emitted
│ │
│ │ # Model selection status (unavailable/degraded runs):
│ └── model_selection_status.json # Reason code and exception details
│
├── 40_decomposition/
│ ├── summary_metrics.nc # NetCDF decomposition dataset
│ ├── summary_metrics.csv # Tabular decomposition
│ └── plots/ # When export_plots: true
│ ├── channel_contribution_area_chart.png
│ ├── contribution_waterfall_chart.png
│ ├── spend_vs_contribution_chart.png
│ └── roi_bar_chart.png
│
├── 60_response_curves/ # Only when response_curves configured
│ ├── response_curves.nc # NetCDF response curve dataset
│ ├── response_curves.csv # Tabular response curves
│ └── plots/ # When export_plots: true
│ └── response_curves_plot.png
│
└── 70_optimisation/ # Only when optimisation configured
├── optimisation_summary.html # Meridian optimisation HTML report
├── optimised_data.nc # Optimised allocation (NetCDF)
├── optimised_data.csv # Optimised allocation (CSV)
├── nonoptimised_data.nc # Baseline allocation (NetCDF)
├── nonoptimised_data.csv # Baseline allocation (CSV)
├── optimisation_grid.csv # Full optimisation grid
└── plots/ # When export_plots: true
├── incremental_outcome_delta_plot.png
├── budget_allocation_optimised_plot.png
├── budget_allocation_nonoptimised_plot.png
├── spend_delta_plot.png
└── optimisation_response_curves_plot.png
Stage details
00_run_metadata
Always present. Created first.
Artefact
Format
Description
config.source.yaml
YAML
Verbatim copy of the source config for this run. On refresh, this is copied from the source run’s archived config.source.yaml.
config.resolved.yaml
YAML
Config after relative path resolution. Does not include runtime-only fields (output_dir, run_name).
Reason code, warning details, and optional exception type.
40_decomposition
Always present.
Artefact
Format
Description
summary_metrics.nc
NetCDF
Full decomposition dataset with coordinates.
summary_metrics.csv
CSV
Flattened tabular decomposition.
plots/channel_contribution_area_chart.png
PNG
Channel contribution over time.
plots/contribution_waterfall_chart.png
PNG
Contribution waterfall breakdown.
plots/spend_vs_contribution_chart.png
PNG
Spend vs. contribution scatter.
plots/roi_bar_chart.png
PNG
ROI by channel bar chart.
60_response_curves
Present only when the response_curves YAML section is configured.
Artefact
Format
Description
response_curves.nc
NetCDF
Response curve dataset across spend multipliers.
response_curves.csv
CSV
Flattened tabular response curves.
plots/response_curves_plot.png
PNG
Response curve visualisation.
70_optimisation
Present only when the optimisation YAML section is configured.
Artefact
Format
Description
optimisation_summary.html
HTML
Meridian optimisation summary report.
optimised_data.nc
NetCDF
Optimised budget allocation.
optimised_data.csv
CSV
Tabular optimised allocation.
nonoptimised_data.nc
NetCDF
Baseline (non-optimised) allocation.
nonoptimised_data.csv
CSV
Tabular baseline allocation.
optimisation_grid.csv
CSV
Full optimisation grid dataset.
plots/incremental_outcome_delta_plot.png
PNG
Incremental outcome delta.
plots/budget_allocation_optimised_plot.png
PNG
Optimised allocation chart.
plots/budget_allocation_nonoptimised_plot.png
PNG
Baseline allocation chart.
plots/spend_delta_plot.png
PNG
Spend delta between optimised and baseline.
plots/optimisation_response_curves_plot.png
PNG
Optimisation response curves.
Reading order for analysts
For a quick assessment of a completed run:
run_manifest.json — run identity, timing, stage completion
00_run_metadata/config.source.yaml — what was authored
00_run_metadata/input_data_provenance.json — dataset identity and shape
30_model_assessment/diagnostics_bundle.json — diagnostics export state
30_model_assessment/model_results_summary.html — visual model summary
40_decomposition/summary_metrics.csv — easiest tabular output to inspect
For model selection:
30_model_assessment/loo_summary.json or model_selection_status.json
For scenario analysis:
60_response_curves/response_curves.csv
70_optimisation/optimisation_summary.html
Validation spec schema reference
The validation_spec.json artefact is written to 10_validation/ for every
validation-aware pipeline run. It records the concrete validation provenance
for that specific run, including the holdout strategy, split geometry, and
date windows. Current runs write validation-spec version 2, which also binds
the source coordinate fingerprints and the execution prefix used by the split.
Fields
Field
Type
Description
mode
"validation" | "final_fit"
Whether this is a validation split or the final production fit.
Whether the holdout mask was auto-generated by meridian-tools.
run_name_suffix
str
Suffix appended to the run name for this split.
holdout_shape
list[int] | null
Shape of the holdout mask array. null for final-fit runs.
train_indices
list[int]
Integer indices into the time axis used for training.
test_indices
list[int]
Integer indices into the time axis used for testing. Empty for final-fit runs.
train_dates
list[str]
Date values corresponding to train_indices.
test_dates
list[str]
Date values corresponding to test_indices. Empty for final-fit runs.
validation_spec_version
int
Version of the validation-spec schema. Current value is 2.
data_binding
object | null
Version-2 coordinate binding. Present for generated validation and final-fit runs, null for authored-holdout runs.
Version-2 data_binding
data_binding records the source coordinate fingerprints and the execution
prefix used by a generated split. Rolling-origin validation fits only through
the end of each split’s test window, not through future observations. The
binding lets refresh execution reject source data whose coordinates no longer
match the stored split.
Field
Type
Description
coordinate_canonicalization_version
int
Coordinate string canonicalisation version. Current value is 1.
source_time_count
int
Number of time coordinates in the source dataset.
source_time_sha256
str
SHA-256 digest of all source time coordinates.
execution_time_count
int
Number of time coordinates visible to this fit.
execution_time_sha256
str
SHA-256 digest of the execution prefix.
execution_end_date
str
Last date in the execution prefix.
geo_mode
"national" | "geo"
Whether the model is national or geo-indexed.
geo_count
int
Number of geos, or 0 for national data.
geo_sha256
str | null
SHA-256 digest of geo coordinates, or null for national data.
Mode and strategy combinations
Mode
Strategy
Holdout source
Description
validation
blocked_tail
generated_validation
Auto-generated contiguous tail holdout.
validation
rolling_origin
generated_validation
One split from an expanding-window plan.
validation
authored_holdout
authored_model_spec
User-provided holdout mask from YAML.
final_fit
none
none
Full-sample production fit after validation.
Invariants
Validation-mode specs always have a non-null holdout_shape.
Final-fit specs always have holdout_shape: null, empty test_indices, and empty test_dates.
train_indices and train_dates always have matching lengths.
test_indices and test_dates always have matching lengths.
Authored-holdout specs have empty train_indices, test_indices, train_dates, and test_dates.
Version-2 generated validation and final-fit specs have non-null
data_binding.
Rolling-origin split specs set execution_time_count to the end of that
split’s test window. Later source observations are not visible to that fit.
The actual holdout mask array (boolean NumPy array) is not stored in
validation_spec.json because it can be large for geo-panel models
(n_geos × n_times). Only its holdout_shape is recorded. The mask is
injected into the Meridian model at runtime and can be reconstructed from
train_indices, test_indices, and the data geometry.
Full YAML configuration for one meridian-tools run. This is the top-level
model returned by load_yaml_config.
Attribute
Type
Default
project
ProjectConfig
ProjectConfig()
data
CsvDataConfig
required
model_spec
ModelSpecConfig
ModelSpecConfig()
fit
FitConfig
FitConfig()
validation
ValidationConfig
ValidationConfig()
exports
ExportsConfig
ExportsConfig()
response_curves
`ResponseCurvesConfig
None`
optimisation
`OptimisationConfig
None`
PipelineRunConfig
@dataclass(frozen=True)classPipelineRunConfig
Runtime options that sit outside the YAML file. Passed to run_pipeline.
Attribute
Type
Default
Description
config_path
Path
required
Path to the YAML config file.
output_dir
Path
Path("runs")
Directory for run output.
run_name
`str
None`
None
validation_spec
`ValidationRunSpec
None`
None
apply_run_name_suffix
bool
True
Whether to append validation-aware suffixes to the run name.
source_config_path
`Path
None`
None
ProjectConfig
classProjectConfig(BaseModel)
Attribute
Type
Default
name
str
"meridian-project"
CsvDataConfig
classCsvDataConfig(BaseModel)
CSV loader configuration compatible with Meridian’s CsvDataLoader.
Attribute
Type
Default
path
Path
required
kpi_type
Literal["revenue", "non-revenue"]
"revenue"
coord_to_columns
dict[str, Any]
required
media_to_channel
`dict[str, str]
None`
media_spend_to_channel
`dict[str, str]
None`
reach_to_channel
`dict[str, str]
None`
frequency_to_channel
`dict[str, str]
None`
rf_spend_to_channel
`dict[str, str]
None`
organic_reach_to_channel
`dict[str, str]
None`
organic_frequency_to_channel
`dict[str, str]
None`
ModelSpecConfig
classModelSpecConfig(BaseModel)
Attribute
Type
Default
kwargs
dict[str, Any]
{}
priors
`PriorsConfig
None`
DistributionSpec
classDistributionSpec(BaseModel)
One YAML-authored TensorFlow Probability distribution.
Supported distribution names are Normal, LogNormal, TruncatedNormal, and
Beta. Required parameters depend on the distribution and extra distribution
parameters are rejected.
ChannelPriorSpec
classChannelPriorSpec(BaseModel)
A media prior with a default distribution and optional per-channel overrides.
Attribute
Type
Default
default
DistributionSpec
required
channels
dict[str, DistributionSpec]
{}
PriorsConfig
classPriorsConfig(BaseModel)
YAML-friendly subset of Meridian media prior distributions.
Attribute
Type
Default
roi_m
`DistributionSpec
ChannelPriorSpec
mroi_m
`DistributionSpec
ChannelPriorSpec
alpha_m
`DistributionSpec
ChannelPriorSpec
FitConfig
classFitConfig(BaseModel)
Sampling configuration for Meridian posterior fitting.
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.
Return JSON-serializable applied prior distributions from a Meridian model.
The summary is based on the constructed model’s broadcast prior distribution,
so it records what Meridian will use rather than only echoing YAML input.
Parameters:
model — Constructed Meridian model instance.
Returns: Dictionary keyed by Meridian prior parameter name.
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 and 4 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 and 4 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.
model_selection_warnings_path
Path | None
Path to model_selection_warnings.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 and 4 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.
Writes through a private same-directory temporary file and atomically replaces
the destination. Existing destination permission bits are preserved on
overwrite; new files use the normal mode implied by the process umask.
Validate that manifest artefact paths are relative regular files beneath
run_dir, then return normalised POSIX relative paths. The validator rejects
absolute paths, lexical .. components, paths that resolve outside the run
directory, missing paths, directories, and special files. Internal symlinks are
accepted only when they resolve to regular files inside the run directory.
Parameters:
run_dir - The run directory root.
artifacts - Mapping of artefact names to file paths.
Returns: Dictionary mapping artefact names to validated 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, 3, or 4).
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, 3, and 4 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 and 4 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 and 4 runs. diagnostics_bundle
remains optional, so older or partial runs can still be loaded without it.