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 3. Versions 0, 1, and 2 are supported for backward compatibility when loading older run directories.

Top-level fields

Field Type Description
manifest_version int Schema version (0, 1, 2, or 3).
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:

  • config_source, config_resolved, input_data_provenance (from 00_run_metadata)
  • validation_spec (from 10_validation)
  • meridian_model (from 20_model_fit)
  • diagnostics_bundle, model_results_summary (from 30_model_assessment)
  • summary_metrics_csv, summary_metrics_nc (from 40_decomposition)

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 the manifest are relative to 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.

Example stage record:

{
  "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"
  }
}

Stage names and ordering

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 layer 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 runs

These are enforced by _require_manifest_artifact in load_run_record. If a required entry is missing, a LifecycleError is raised.

The diagnostics_bundle artefact is treated as optional by the lifecycle loader. If it is absent from the manifest, RunRecord.diagnostics_bundle_path is None. However, diagnostics_bundle is listed in REQUIRED_MANIFEST_ARTIFACTS and validated at run completion time — so new runs always produce it, but older or partial runs can still be loaded without it.

Input-data provenance payload

Manifest version 3 introduces 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": 3,
  "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.3.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"
      }
    },
    {
      "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 3 (current)

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.