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. |
strategy |
"none" | "blocked_tail" | "rolling_origin" | "authored_holdout" |
Validation strategy that produced this run. |
split_label |
str |
Human-readable identifier for the split (e.g. "blocked_tail", "split_01", "final_fit"). |
holdout_source |
"generated_validation" | "authored_model_spec" | "none" |
How the holdout mask was produced. |
generated_holdout |
bool |
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, emptytest_indices, and emptytest_dates. train_indicesandtrain_datesalways have matching lengths.test_indicesandtest_datesalways have matching lengths.- Authored-holdout specs have empty
train_indices,test_indices,train_dates, andtest_dates. - Version-2 generated validation and final-fit specs have non-null
data_binding. - Rolling-origin split specs set
execution_time_countto the end of that split’s test window. Later source observations are not visible to that fit.
Example: blocked tail validation
Example: rolling origin split
Example: final fit
Note on holdout mask storage
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.