Configuration guide
meridian-tools is driven by one YAML configuration file. This guide explains
every section, its purpose, and its constraints. For a field-level schema
reference, see yaml-schema.md.
Configuration philosophy
The YAML file owns the authored project definition: project metadata, data
paths, model specification, fit settings, validation strategy, and export
switches. Runtime-only values — output_dir, run_name, and concrete
validation_spec — belong in PipelineRunConfig or CLI flags, not in the YAML
file. This separation ensures that the same YAML file can drive multiple runs
with different runtime options while remaining reproducible.
Minimal valid config
This is the smallest config that will pass validation. It uses defaults for everything else: no validation, all exports enabled, no response curves, no optimisation.
Section reference
project
Top-level project metadata.
name— Human-readable project name. Used as the base for run directory names unless overridden by--run-nameat runtime.
data
CSV data loader configuration. Maps directly to Meridian’s CsvDataLoader.
path— Path to the CSV data file. Relative paths are resolved against the directory containing the YAML config file, not the current working directory.kpi_type— Either"revenue"or"non-revenue". Controls how Meridian interprets the KPI column.coord_to_columns— Maps Meridian coordinate names to CSV column names.timeis required.geois optional (omit for national models).
model_spec
Raw keyword arguments forwarded to Meridian’s ModelSpec.
kwargs— Dictionary passed through toModelSpec(**kwargs). Supports any argument that Meridian’sModelSpecaccepts.- Special handling for
holdout_id: if present inkwargs, the run is treated as an “authored holdout” validation run. See the validation guide for details.
fit
Sampling configuration for Meridian posterior fitting.
All fields have sensible defaults. Override only what you need.
seed— Accepts a single integer, a list of integers (one per chain), ornullfor non-deterministic sampling.sample_prior_draws— If set, prior predictive samples are drawn before posterior sampling. This is optional and primarily for model diagnostics.
validation
Validation and holdout orchestration settings. See the validation guide for strategy selection advice.
strategy— One of"none","blocked_tail", or"rolling_origin".holdout_size— Required forblocked_tail. Number of time periods to hold out from the end of the series.initial_train_size,test_size— Required forrolling_origin.step_size— Optional forrolling_origin. Must equaltest_sizeif set. Defaults totest_size.max_splits— Optional forrolling_origin. Must be at least 2.
Validation rules:
blocked_tailrejects rolling-origin parameters.rolling_originrejectsholdout_size.nonerejects all holdout and rolling-origin parameters.- Legacy
holdout_sizewithout explicitstrategyis rejected.
exports
Output switches for diagnostics and model-selection artefacts.
All fields have defaults. If the entire exports section is omitted,
all exports are enabled with default settings.
response_curves
Optional. If omitted, the response curves stage is skipped.
spend_multipliers— Required. Non-empty list of non-negative floats.confidence_level— Must be strictly between 0 and 1.
optimisation
Optional. If omitted, the optimisation stage is skipped.
start_date,end_date— ISO formatYYYY-MM-DD.end_datemust be on or afterstart_date.budget.mode— Either"fixed_total"(absolute budget) or"relative_reference_window_total"(multiplier against the reference window’s total spend).budget.value— Positive float. Forfixed_total, this is the absolute budget. Forrelative_reference_window_total, this is a multiplier (e.g.1.1means 110% of the reference window total).
Validation strictness
All configuration models use Pydantic’s extra="forbid" mode. Any unexpected
key in the YAML file will produce a clear validation error. This prevents
silent misconfiguration from typos or outdated keys.
Path resolution
Relative paths in data.path are resolved against the directory containing the
YAML config file, not the current working directory. This means:
The resolved path is written to config.resolved.yaml in the run directory.
The original authored path is preserved in config.source.yaml.
Wrapper-owned preflight
Before meridian-tools creates a dated run directory, it performs one narrow
wrapper-owned preflight check on the authored config and the resolved input
CSV. Phase 10 keeps this boundary intentionally small so the wrapper does not
become a second Meridian schema layer.
The wrapper checks exactly:
- the resolved
data.pathexists 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_columnsexists in the header - every authored list member in
data.coord_to_columnsexists in the header - every authored key in
data.media_to_channelexists in the header - every authored key in
data.media_spend_to_channelexists in the header - every authored key in
data.reach_to_channelexists in the header - every authored key in
data.frequency_to_channelexists in the header - every authored key in
data.rf_spend_to_channelexists in the header - every authored key in
data.organic_reach_to_channelexists in the header - every authored key in
data.organic_frequency_to_channelexists in the header - authored list-valued coord families are non-empty
- authored mapping fields above are non-empty
coord_to_columns.mediaandmedia_to_channelmust be authored togethercoord_to_columns.media_spendandmedia_spend_to_channelmust be authored togethercoord_to_columns.reach,coord_to_columns.frequency,reach_to_channel, andfrequency_to_channelmust be authored togethercoord_to_columns.rf_spendandrf_spend_to_channelmust be authored togethercoord_to_columns.organic_reachandorganic_reach_to_channelmust be authored togethercoord_to_columns.organic_frequencyandorganic_frequency_to_channelmust be authored together
Matching is exact and case-sensitive. The wrapper does not normalise headers, apply aliases, or use fuzzy matching.
What remains Meridian-owned:
- deep
ModelSpecsemantics - fit-dependent tensor or shape constraints
- statistical validity checks that depend on model construction or sampling
So Phase 10 moves obvious wrapper-detectable mistakes earlier, but it does not promise to catch everything Meridian may reject later.