{
  "$defs": {
    "About": {
      "additionalProperties": false,
      "description": "The plain-language card of one catalog item.\n\nEvery field except the expert ones is required, so an About that validates is\nstructurally complete; :func:`about_issues` adds the editorial rules (one or two\nsentences, no jargon in the summary, known chooser tags, related ids that exist).",
      "examples": [
        {
          "assumptions": [
            "Numbers can be added up (spend, sales); averages are averaged"
          ],
          "avoid_when": [
            "Your data already has one row per week"
          ],
          "data_needs": [
            "A date column"
          ],
          "difficulty": "beginner",
          "example": "Daily TV spend of 100 each day becomes 700 for the week.",
          "fits": {
            "goal": [
              "check_data"
            ]
          },
          "outputs": [
            "The same columns, one row per week"
          ],
          "related": [
            "core.calendar"
          ],
          "summary_plain": "Adds up daily numbers into one number per week (or month), so that every row covers the same length of time.",
          "title": "Weekly totals",
          "typical_runtime": "instant",
          "use_when": [
            "Your data is daily but you want to plan or report by week"
          ]
        }
      ],
      "properties": {
        "assumptions": {
          "items": {
            "type": "string"
          },
          "maxItems": 10,
          "minItems": 1,
          "title": "Assumptions",
          "type": "array"
        },
        "avoid_when": {
          "items": {
            "type": "string"
          },
          "maxItems": 10,
          "minItems": 1,
          "title": "Avoid When",
          "type": "array"
        },
        "data_needs": {
          "items": {
            "type": "string"
          },
          "maxItems": 10,
          "minItems": 1,
          "title": "Data Needs",
          "type": "array"
        },
        "difficulty": {
          "$ref": "#/$defs/Difficulty"
        },
        "example": {
          "description": "A tiny example",
          "maxLength": 600,
          "minLength": 10,
          "title": "Example",
          "type": "string"
        },
        "expert_notes": {
          "anyOf": [
            {
              "maxLength": 4000,
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Maths, estimator details, caveats for experts",
          "title": "Expert Notes"
        },
        "fits": {
          "additionalProperties": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "description": "Chooser tags: question id -> the answers this item suits",
          "maxProperties": 16,
          "title": "Fits",
          "type": "object"
        },
        "outputs": {
          "items": {
            "type": "string"
          },
          "maxItems": 10,
          "minItems": 1,
          "title": "Outputs",
          "type": "array"
        },
        "references": {
          "items": {
            "$ref": "#/$defs/AboutReference"
          },
          "maxItems": 10,
          "title": "References",
          "type": "array"
        },
        "related": {
          "description": "Ids of related catalog items (models, steps, nodes, checks, templates)",
          "items": {
            "type": "string"
          },
          "maxItems": 16,
          "title": "Related",
          "type": "array"
        },
        "summary_plain": {
          "description": "One or two sentences without jargon: what it does for you",
          "maxLength": 400,
          "minLength": 20,
          "title": "Summary Plain",
          "type": "string"
        },
        "title": {
          "description": "A human name",
          "maxLength": 80,
          "minLength": 3,
          "title": "Title",
          "type": "string"
        },
        "typical_runtime": {
          "$ref": "#/$defs/TypicalRuntime"
        },
        "use_when": {
          "items": {
            "type": "string"
          },
          "maxItems": 10,
          "minItems": 1,
          "title": "Use When",
          "type": "array"
        }
      },
      "required": [
        "title",
        "summary_plain",
        "use_when",
        "avoid_when",
        "data_needs",
        "assumptions",
        "outputs",
        "difficulty",
        "typical_runtime",
        "example"
      ],
      "title": "About",
      "type": "object"
    },
    "AboutReference": {
      "additionalProperties": false,
      "description": "A source for the expert detail (a paper, a book chapter, library documentation).",
      "properties": {
        "title": {
          "maxLength": 300,
          "minLength": 3,
          "title": "Title",
          "type": "string"
        },
        "url": {
          "anyOf": [
            {
              "maxLength": 500,
              "pattern": "^https://\\S+$",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Url"
        }
      },
      "required": [
        "title"
      ],
      "title": "AboutReference",
      "type": "object"
    },
    "Aggregation": {
      "additionalProperties": false,
      "description": "Reduce outputs over dims before summarising (validity depends on representation).",
      "properties": {
        "how": {
          "default": "sum",
          "enum": [
            "sum",
            "mean",
            "min",
            "max"
          ],
          "title": "How",
          "type": "string"
        },
        "over": {
          "items": {
            "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
            "type": "string"
          },
          "maxItems": 16,
          "minItems": 1,
          "title": "Over",
          "type": "array"
        }
      },
      "required": [
        "over"
      ],
      "title": "Aggregation",
      "type": "object"
    },
    "AsOfSplit": {
      "additionalProperties": false,
      "description": "Train on coords up to and including ``as_of``; hold out the rest (optionally ``gap``).",
      "properties": {
        "after_step": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Stage the split happens at (a step id or 'raw'); default: end of the stateless prefix",
          "title": "After Step"
        },
        "allow_leakage": {
          "default": false,
          "description": "Downgrade LEAKAGE_RISK to a warning (acknowledged)",
          "title": "Allow Leakage",
          "type": "boolean"
        },
        "as_of": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "integer"
            },
            {
              "type": "number"
            },
            {
              "type": "boolean"
            }
          ],
          "title": "As Of"
        },
        "dim": {
          "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
          "title": "Dim",
          "type": "string"
        },
        "gap": {
          "default": 0,
          "minimum": 0,
          "title": "Gap",
          "type": "integer"
        },
        "kind": {
          "const": "as_of",
          "title": "Kind",
          "type": "string"
        }
      },
      "required": [
        "kind",
        "dim",
        "as_of"
      ],
      "title": "AsOfSplit",
      "type": "object"
    },
    "Backtest": {
      "additionalProperties": false,
      "description": "Refit-and-score at several ``as_of`` coords along ``dim``.",
      "properties": {
        "apiVersion": {
          "const": "mapi/v1",
          "title": "Apiversion",
          "type": "string"
        },
        "as_of": {
          "items": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "integer"
              },
              {
                "type": "number"
              },
              {
                "type": "boolean"
              }
            ]
          },
          "maxItems": 500,
          "minItems": 1,
          "title": "As Of",
          "type": "array"
        },
        "base": {
          "description": "Spec revision spec://project/name@rN",
          "pattern": "^spec://([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)/([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)@(r\\d{1,9}|\\d{1,9}|sha256:[0-9a-f]{64})$",
          "title": "Base",
          "type": "string"
        },
        "dim": {
          "default": "time",
          "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
          "title": "Dim",
          "type": "string"
        },
        "execution": {
          "anyOf": [
            {
              "$ref": "#/$defs/ExecutionBlock"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "horizon": {
          "anyOf": [
            {
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Horizon"
        },
        "kind": {
          "const": "Backtest",
          "title": "Kind",
          "type": "string"
        },
        "metadata": {
          "$ref": "#/$defs/Metadata"
        },
        "metrics": {
          "items": {
            "pattern": "^[a-z][a-z0-9_]{0,63}$",
            "type": "string"
          },
          "title": "Metrics",
          "type": "array"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "metadata",
        "base",
        "as_of"
      ],
      "title": "Backtest",
      "type": "object"
    },
    "Binding": {
      "additionalProperties": false,
      "description": "Canonical name \u2192 dataset name, for dims and variables (``geo: market``).\n\nNames that are not bound keep their dataset name. The binding is stored in the bundle\nand reversed on every output by default.",
      "properties": {
        "dims": {
          "maxProperties": 256,
          "patternProperties": {
            "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$": {
              "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
              "type": "string"
            }
          },
          "title": "Dims",
          "type": "object"
        },
        "vars": {
          "maxProperties": 4096,
          "patternProperties": {
            "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$": {
              "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
              "type": "string"
            }
          },
          "title": "Vars",
          "type": "object"
        }
      },
      "title": "Binding",
      "type": "object"
    },
    "BusinessPriors": {
      "additionalProperties": false,
      "description": "Beliefs in business units, per channel (keys are channel *labels* as in the data),\nand/or about the baseline. At least one belief is stated: a baseline belief alone is\nfine (channels without a belief keep the model's default priors).",
      "examples": [
        {
          "baseline_share": {
            "credibility": 0.8,
            "share": [
              0.5,
              0.8
            ]
          },
          "channels": {
            "search": {
              "credibility": 0.9,
              "roi": [
                2.0,
                6.0
              ]
            },
            "social": {
              "contribution_share": [
                0.02,
                0.1
              ]
            },
            "tv": {
              "credibility": 0.8,
              "roi": [
                1.5,
                4.0
              ]
            }
          },
          "kpi_units": "EUR",
          "spend_units": "EUR"
        }
      ],
      "properties": {
        "baseline_share": {
          "anyOf": [
            {
              "$ref": "#/$defs/ShareBelief"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "channels": {
          "additionalProperties": {
            "$ref": "#/$defs/ChannelBelief"
          },
          "maxProperties": 64,
          "title": "Channels",
          "type": "object"
        },
        "kpi_units": {
          "anyOf": [
            {
              "maxLength": 64,
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "examples": [
            "EUR"
          ],
          "title": "Kpi Units"
        },
        "spend_units": {
          "anyOf": [
            {
              "maxLength": 64,
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "examples": [
            "EUR"
          ],
          "title": "Spend Units"
        }
      },
      "title": "BusinessPriors",
      "type": "object"
    },
    "Calibration": {
      "additionalProperties": false,
      "description": "The ``calibration`` block of a ``ModelSpec``: beliefs and experiment results the model\nshould respect. ``prior_translation_run`` records which ``translate_priors`` run produced\nthe priors in ``model.settings.priors`` (lineage only).",
      "examples": [
        {
          "business_priors": {
            "baseline_share": {
              "credibility": 0.8,
              "share": [
                0.5,
                0.8
              ]
            },
            "channels": {
              "search": {
                "credibility": 0.9,
                "roi": [
                  2.0,
                  6.0
                ]
              },
              "social": {
                "contribution_share": [
                  0.02,
                  0.1
                ]
              },
              "tv": {
                "credibility": 0.8,
                "roi": [
                  1.5,
                  4.0
                ]
              }
            },
            "kpi_units": "EUR",
            "spend_units": "EUR"
          },
          "lift_tests": [
            {
              "channel": "tv",
              "ci": [
                -380000.0,
                -140000.0
              ],
              "ci_level": 0.9,
              "description": "TV off in Germany for four weeks",
              "end": "2026-05-03",
              "geo": "de",
              "id": "tv-holdout-2026q2",
              "kpi_delta": -260000.0,
              "spend_delta": -120000.0,
              "start": "2026-04-06"
            }
          ]
        }
      ],
      "properties": {
        "business_priors": {
          "anyOf": [
            {
              "$ref": "#/$defs/BusinessPriors"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "lift_tests": {
          "items": {
            "$ref": "#/$defs/LiftTest"
          },
          "maxItems": 500,
          "title": "Lift Tests",
          "type": "array"
        },
        "prior_translation_run": {
          "anyOf": [
            {
              "pattern": "^run_[0-9a-z]{26}$",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Prior Translation Run"
        }
      },
      "title": "Calibration",
      "type": "object"
    },
    "Campaign": {
      "additionalProperties": false,
      "description": "A plugin-owned fit\u2192recommend loop (e.g. Bayesian optimisation) in one sandbox run.",
      "properties": {
        "apiVersion": {
          "const": "mapi/v1",
          "title": "Apiversion",
          "type": "string"
        },
        "base": {
          "description": "Spec revision spec://project/name@rN",
          "pattern": "^spec://([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)/([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)@(r\\d{1,9}|\\d{1,9}|sha256:[0-9a-f]{64})$",
          "title": "Base",
          "type": "string"
        },
        "batch_size": {
          "default": 1,
          "maximum": 1000,
          "minimum": 1,
          "title": "Batch Size",
          "type": "integer"
        },
        "candidates": {
          "anyOf": [
            {
              "description": "Dataset reference dataset://project/name@version",
              "examples": [
                "dataset://growth/eu_media_daily@latest"
              ],
              "pattern": "^dataset://([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)/([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)(?:@(latest|v\\d{1,9}|\\d{1,9}|sha256:[0-9a-f]{64}))?$",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Candidates"
        },
        "execution": {
          "anyOf": [
            {
              "$ref": "#/$defs/ExecutionBlock"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "kind": {
          "const": "Campaign",
          "title": "Kind",
          "type": "string"
        },
        "metadata": {
          "$ref": "#/$defs/Metadata"
        },
        "rounds": {
          "maximum": 1000,
          "minimum": 1,
          "title": "Rounds",
          "type": "integer"
        },
        "seed": {
          "anyOf": [
            {
              "exclusiveMaximum": 4294967296,
              "minimum": 0,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Seed"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "metadata",
        "base",
        "rounds"
      ],
      "title": "Campaign",
      "type": "object"
    },
    "ChannelBelief": {
      "additionalProperties": false,
      "description": "What the user believes about one channel: exactly one of ``roi`` or\n``contribution_share``, held with ``credibility``.\n\n* ``roi``: KPI units gained per spend unit over the fit window (``[1.5, 4]`` = \"every\n  euro returns between 1.5 and 4 euros of revenue\");\n* ``contribution_share``: the channel's share of the KPI over the fit window.",
      "properties": {
        "contribution_share": {
          "anyOf": [
            {
              "maxItems": 2,
              "minItems": 2,
              "prefixItems": [
                {
                  "type": "number"
                },
                {
                  "type": "number"
                }
              ],
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "examples": [
            [
              0.05,
              0.15
            ]
          ],
          "title": "Contribution Share"
        },
        "credibility": {
          "default": 0.8,
          "description": "Probability that the true value lies inside the range (0.8 = 'I am 80% sure')",
          "maximum": 0.99,
          "minimum": 0.5,
          "title": "Credibility",
          "type": "number"
        },
        "roi": {
          "anyOf": [
            {
              "maxItems": 2,
              "minItems": 2,
              "prefixItems": [
                {
                  "type": "number"
                },
                {
                  "type": "number"
                }
              ],
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "examples": [
            [
              1.5,
              4.0
            ]
          ],
          "title": "Roi"
        }
      },
      "title": "ChannelBelief",
      "type": "object"
    },
    "Checkpoint": {
      "additionalProperties": false,
      "description": "Resumable checkpoints: every N draws (samplers) or every N epochs (v0.15: networks).\n\nExactly one is set. The model must be checkpointable; otherwise validation warns and\nthe run ignores it.",
      "properties": {
        "every_draws": {
          "anyOf": [
            {
              "maximum": 1000000,
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Every Draws"
        },
        "every_epochs": {
          "anyOf": [
            {
              "maximum": 10000,
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "v0.15: networks trained in epochs",
          "title": "Every Epochs"
        }
      },
      "title": "Checkpoint",
      "type": "object"
    },
    "CollectionRead": {
      "additionalProperties": false,
      "description": "How a model that reads datasets sees a collection: a seeded sample as\n``pixels(image, y, x, channel)`` (``ModelSpec`` ``data.collection``).",
      "properties": {
        "max_samples": {
          "default": 5000,
          "maximum": 100000,
          "minimum": 1,
          "title": "Max Samples",
          "type": "integer"
        },
        "mode": {
          "default": "auto",
          "enum": [
            "auto",
            "gray",
            "rgb"
          ],
          "title": "Mode",
          "type": "string"
        },
        "resize": {
          "default": "stretch",
          "enum": [
            "stretch",
            "crop",
            "pad"
          ],
          "title": "Resize",
          "type": "string"
        },
        "seed": {
          "anyOf": [
            {
              "exclusiveMaximum": 4294967296,
              "minimum": 0,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Default: the fit seed",
          "title": "Seed"
        },
        "size": {
          "anyOf": [
            {
              "maxItems": 2,
              "minItems": 2,
              "prefixItems": [
                {
                  "type": "integer"
                },
                {
                  "type": "integer"
                }
              ],
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "(height, width); default: the collection's size (needed when it has none)",
          "title": "Size"
        },
        "stratify": {
          "anyOf": [
            {
              "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": "label",
          "description": "Keep the share of each level of this var or coord (none: uniform)",
          "title": "Stratify"
        }
      },
      "title": "CollectionRead",
      "type": "object"
    },
    "ColumnSplit": {
      "additionalProperties": false,
      "description": "Hold out the rows whose value in ``column`` is one of ``holdout`` (a fixed split read\nfrom the data, v0.14).\n\n``column`` is a coord or a 1-D data variable along ``dim``. Values compare as text, so\n``holdout: [1]`` matches a stored ``1`` or ``\"1\"``. With ``train`` set, rows in neither\nlist are dropped; else every other row trains.",
      "properties": {
        "after_step": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Stage the split happens at (a step id or 'raw'); default: end of the stateless prefix",
          "title": "After Step"
        },
        "allow_leakage": {
          "default": false,
          "description": "Downgrade LEAKAGE_RISK to a warning (acknowledged)",
          "title": "Allow Leakage",
          "type": "boolean"
        },
        "column": {
          "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
          "title": "Column",
          "type": "string"
        },
        "dim": {
          "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
          "title": "Dim",
          "type": "string"
        },
        "holdout": {
          "items": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "integer"
              },
              {
                "type": "number"
              },
              {
                "type": "boolean"
              }
            ]
          },
          "maxItems": 64,
          "minItems": 1,
          "title": "Holdout",
          "type": "array"
        },
        "kind": {
          "const": "column",
          "title": "Kind",
          "type": "string"
        },
        "train": {
          "anyOf": [
            {
              "items": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "integer"
                  },
                  {
                    "type": "number"
                  },
                  {
                    "type": "boolean"
                  }
                ]
              },
              "maxItems": 64,
              "minItems": 1,
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Train"
        }
      },
      "required": [
        "kind",
        "dim",
        "column"
      ],
      "title": "ColumnSplit",
      "type": "object"
    },
    "DataBlock": {
      "additionalProperties": false,
      "description": "The dataset, side tables, binding to canonical names and the split.\n\nFor a tree dataset (M4), ``nodes`` picks the nodes whose variables are merged into the\nONE flat dataset the pipeline sees (:meth:`mapi_spec.tree.TreeSchema.flat`), aligned per\n``join``. Without ``nodes`` a tree dataset's root node is read (when it has variables).\n``nodes`` on a plain dataset is an error. The binding applies to the merged names.\n\nFor an image collection (v0.15), ``collection`` says how a model that reads datasets\nsees it (a seeded sample); a model that trains on batches reads every image.",
      "properties": {
        "bind": {
          "$ref": "#/$defs/Binding"
        },
        "collection": {
          "anyOf": [
            {
              "$ref": "#/$defs/CollectionRead"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "v0.15: an image collection read by a model that reads datasets: a seeded sample as pixels(image, y, x, channel)"
        },
        "dataset": {
          "description": "Dataset reference dataset://project/name@version",
          "examples": [
            "dataset://growth/eu_media_daily@latest"
          ],
          "pattern": "^dataset://([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)/([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)(?:@(latest|v\\d{1,9}|\\d{1,9}|sha256:[0-9a-f]{64}))?$",
          "title": "Dataset",
          "type": "string"
        },
        "join": {
          "default": "exact",
          "description": "M4: how the coords of the selected nodes align (xarray merge join)",
          "enum": [
            "exact",
            "inner",
            "outer"
          ],
          "title": "Join",
          "type": "string"
        },
        "nodes": {
          "anyOf": [
            {
              "maxProperties": 64,
              "minProperties": 1,
              "patternProperties": {
                "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$": {
                  "$ref": "#/$defs/NodeSelect"
                }
              },
              "type": "object"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "M4: tree datasets: the nodes merged into the pipeline input",
          "title": "Nodes"
        },
        "side_tables": {
          "maxProperties": 32,
          "patternProperties": {
            "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$": {
              "$ref": "#/$defs/SideTable"
            }
          },
          "title": "Side Tables",
          "type": "object"
        },
        "split": {
          "anyOf": [
            {
              "discriminator": {
                "mapping": {
                  "as_of": "#/$defs/AsOfSplit",
                  "column": "#/$defs/ColumnSplit",
                  "last_per_group": "#/$defs/LastPerGroupSplit",
                  "leave_group_out": "#/$defs/LeaveGroupOutSplit",
                  "mask_block": "#/$defs/MaskBlockSplit",
                  "stratified": "#/$defs/StratifiedSplit",
                  "time_holdout": "#/$defs/TimeHoldoutSplit"
                },
                "propertyName": "kind"
              },
              "oneOf": [
                {
                  "$ref": "#/$defs/TimeHoldoutSplit"
                },
                {
                  "$ref": "#/$defs/LastPerGroupSplit"
                },
                {
                  "$ref": "#/$defs/AsOfSplit"
                },
                {
                  "$ref": "#/$defs/LeaveGroupOutSplit"
                },
                {
                  "$ref": "#/$defs/MaskBlockSplit"
                },
                {
                  "$ref": "#/$defs/ColumnSplit"
                },
                {
                  "$ref": "#/$defs/StratifiedSplit"
                }
              ]
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Split"
        }
      },
      "required": [
        "dataset"
      ],
      "title": "DataBlock",
      "type": "object"
    },
    "Difficulty": {
      "description": "How much statistical background an item needs to use well.",
      "enum": [
        "beginner",
        "intermediate",
        "expert"
      ],
      "title": "Difficulty",
      "type": "string"
    },
    "EvaluateBlock": {
      "additionalProperties": false,
      "properties": {
        "metrics": {
          "items": {
            "pattern": "^[a-z][a-z0-9_]{0,63}$",
            "type": "string"
          },
          "maxItems": 32,
          "title": "Metrics",
          "type": "array"
        }
      },
      "title": "EvaluateBlock",
      "type": "object"
    },
    "ExecutionBlock": {
      "additionalProperties": false,
      "properties": {
        "resource_class": {
          "$ref": "#/$defs/ResourceClass",
          "default": "S"
        },
        "timeout": {
          "description": "Duration such as '45m', '1h30m' or '90s'.",
          "examples": [
            "45m",
            "1h30m"
          ],
          "pattern": "^(?=.)(\\d+h)?(\\d+m)?(\\d+s)?$",
          "title": "Timeout",
          "type": "string"
        }
      },
      "title": "ExecutionBlock",
      "type": "object"
    },
    "FitConfig": {
      "additionalProperties": false,
      "description": "Platform fit settings. Plugin-specific limits come from the manifest's ``fit_schema``.",
      "properties": {
        "chains": {
          "anyOf": [
            {
              "maximum": 64,
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Chains"
        },
        "checkpoint": {
          "anyOf": [
            {
              "$ref": "#/$defs/Checkpoint"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "draws": {
          "anyOf": [
            {
              "maximum": 1000000,
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Draws"
        },
        "engine": {
          "anyOf": [
            {
              "pattern": "^[a-z][a-z0-9_]{0,31}$",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Engine"
        },
        "keep": {
          "$ref": "#/$defs/KeepConfig"
        },
        "mode": {
          "$ref": "#/$defs/FitMode",
          "default": "evaluate_then_refit"
        },
        "prior_predictive": {
          "anyOf": [
            {
              "$ref": "#/$defs/PriorPredictive"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "seed": {
          "anyOf": [
            {
              "exclusiveMaximum": 4294967296,
              "minimum": 0,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Seed"
        },
        "target_accept": {
          "anyOf": [
            {
              "exclusiveMaximum": 1,
              "exclusiveMinimum": 0,
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Target Accept"
        },
        "tune": {
          "anyOf": [
            {
              "maximum": 1000000,
              "minimum": 0,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Tune"
        }
      },
      "title": "FitConfig",
      "type": "object"
    },
    "FitMode": {
      "enum": [
        "evaluate_then_refit",
        "train_only"
      ],
      "title": "FitMode",
      "type": "string"
    },
    "FutureCovariates": {
      "description": "Where future values of ``future_required`` covariates come from in a forecast (M3).\n\n``supplied`` (default) needs them in the request's data or scenario\n(``MISSING_FUTURE_COVARIATE`` otherwise). The other policies let the runner extend them\nover the horizon, per series, inside the sandbox: ``carry_last`` repeats the last\nobserved value, ``seasonal_naive`` repeats the value one season earlier (the time dim's\nyearly period), ``zero`` sets them to zero (e.g. \"no spend planned\").",
      "enum": [
        "supplied",
        "carry_last",
        "seasonal_naive",
        "zero"
      ],
      "title": "FutureCovariates",
      "type": "string"
    },
    "Horizon": {
      "additionalProperties": false,
      "properties": {
        "dim": {
          "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
          "title": "Dim",
          "type": "string"
        },
        "periods": {
          "maximum": 100000,
          "minimum": 1,
          "title": "Periods",
          "type": "integer"
        }
      },
      "required": [
        "dim",
        "periods"
      ],
      "title": "Horizon",
      "type": "object"
    },
    "Intervention": {
      "additionalProperties": false,
      "description": "Change ``var`` on the coords selected by ``sel``: exactly one of multiply/add/set.",
      "properties": {
        "add": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Add"
        },
        "multiply": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Multiply"
        },
        "sel": {
          "patternProperties": {
            "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                },
                {
                  "items": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "integer"
                      },
                      {
                        "type": "number"
                      },
                      {
                        "type": "boolean"
                      }
                    ]
                  },
                  "type": "array"
                }
              ]
            }
          },
          "title": "Sel",
          "type": "object"
        },
        "set": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Set"
        },
        "var": {
          "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
          "title": "Var",
          "type": "string"
        }
      },
      "required": [
        "var"
      ],
      "title": "Intervention",
      "type": "object"
    },
    "JsonValue": {},
    "KeepConfig": {
      "additionalProperties": false,
      "description": "Optional groups kept in the bundle.",
      "properties": {
        "log_likelihood": {
          "default": false,
          "title": "Log Likelihood",
          "type": "boolean"
        },
        "posterior_predictive": {
          "anyOf": [
            {
              "$ref": "#/$defs/PosteriorPredictiveKeep"
            },
            {
              "type": "boolean"
            }
          ],
          "default": false,
          "title": "Posterior Predictive"
        },
        "prior": {
          "default": false,
          "title": "Prior",
          "type": "boolean"
        }
      },
      "title": "KeepConfig",
      "type": "object"
    },
    "LastPerGroupSplit": {
      "additionalProperties": false,
      "description": "Hold out the last ``last`` rows along ``dim`` within each group (``min_len`` kept).",
      "properties": {
        "after_step": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Stage the split happens at (a step id or 'raw'); default: end of the stateless prefix",
          "title": "After Step"
        },
        "allow_leakage": {
          "default": false,
          "description": "Downgrade LEAKAGE_RISK to a warning (acknowledged)",
          "title": "Allow Leakage",
          "type": "boolean"
        },
        "dim": {
          "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
          "title": "Dim",
          "type": "string"
        },
        "kind": {
          "const": "last_per_group",
          "title": "Kind",
          "type": "string"
        },
        "last": {
          "default": 1,
          "minimum": 1,
          "title": "Last",
          "type": "integer"
        },
        "min_len": {
          "default": 1,
          "minimum": 1,
          "title": "Min Len",
          "type": "integer"
        },
        "within": {
          "items": {
            "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
            "type": "string"
          },
          "maxItems": 8,
          "minItems": 1,
          "title": "Within",
          "type": "array"
        }
      },
      "required": [
        "kind",
        "dim",
        "within"
      ],
      "title": "LastPerGroupSplit",
      "type": "object"
    },
    "LeaveGroupOutSplit": {
      "additionalProperties": false,
      "description": "Hold out whole groups of ``dim`` (explicit ``groups`` or ``n`` random ones).",
      "properties": {
        "after_step": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Stage the split happens at (a step id or 'raw'); default: end of the stateless prefix",
          "title": "After Step"
        },
        "allow_leakage": {
          "default": false,
          "description": "Downgrade LEAKAGE_RISK to a warning (acknowledged)",
          "title": "Allow Leakage",
          "type": "boolean"
        },
        "dim": {
          "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
          "title": "Dim",
          "type": "string"
        },
        "groups": {
          "anyOf": [
            {
              "items": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "integer"
                  },
                  {
                    "type": "number"
                  },
                  {
                    "type": "boolean"
                  }
                ]
              },
              "maxItems": 10000,
              "minItems": 1,
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Groups"
        },
        "kind": {
          "const": "leave_group_out",
          "title": "Kind",
          "type": "string"
        },
        "n": {
          "anyOf": [
            {
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "N"
        },
        "seed": {
          "anyOf": [
            {
              "exclusiveMaximum": 4294967296,
              "minimum": 0,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Seed"
        }
      },
      "required": [
        "kind",
        "dim"
      ],
      "title": "LeaveGroupOutSplit",
      "type": "object"
    },
    "LiftTest": {
      "additionalProperties": false,
      "description": "One experiment: ``spend_delta`` extra spend on ``channel`` (optionally in one ``geo``)\nfrom ``start`` to ``end`` (inclusive) caused ``kpi_delta`` incremental KPI.\n\nGive the measurement's uncertainty as a standard error ``se`` *or* a confidence interval\n``ci`` at ``ci_level``. A holdout (\"turn the channel off\") is a negative ``spend_delta``\nwith (usually) a negative ``kpi_delta``.",
      "examples": [
        {
          "channel": "tv",
          "ci": [
            -380000.0,
            -140000.0
          ],
          "ci_level": 0.9,
          "description": "TV off in Germany for four weeks",
          "end": "2026-05-03",
          "geo": "de",
          "id": "tv-holdout-2026q2",
          "kpi_delta": -260000.0,
          "spend_delta": -120000.0,
          "start": "2026-04-06"
        }
      ],
      "properties": {
        "channel": {
          "maxLength": 128,
          "minLength": 1,
          "title": "Channel",
          "type": "string"
        },
        "ci": {
          "anyOf": [
            {
              "maxItems": 2,
              "minItems": 2,
              "prefixItems": [
                {
                  "type": "number"
                },
                {
                  "type": "number"
                }
              ],
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Confidence interval of kpi_delta",
          "title": "Ci"
        },
        "ci_level": {
          "default": 0.9,
          "maximum": 0.999,
          "minimum": 0.5,
          "title": "Ci Level",
          "type": "number"
        },
        "description": {
          "anyOf": [
            {
              "maxLength": 500,
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Description"
        },
        "end": {
          "format": "date",
          "title": "End",
          "type": "string"
        },
        "geo": {
          "anyOf": [
            {
              "maxLength": 128,
              "minLength": 1,
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Geo"
        },
        "id": {
          "anyOf": [
            {
              "pattern": "^[a-z0-9][a-z0-9_-]{0,62}$",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Id"
        },
        "kpi_delta": {
          "description": "Measured incremental KPI (KPI units)",
          "title": "Kpi Delta",
          "type": "number"
        },
        "se": {
          "anyOf": [
            {
              "exclusiveMinimum": 0,
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Standard error of kpi_delta",
          "title": "Se"
        },
        "spend_delta": {
          "description": "Extra spend during the test (spend units)",
          "title": "Spend Delta",
          "type": "number"
        },
        "start": {
          "format": "date",
          "title": "Start",
          "type": "string"
        }
      },
      "required": [
        "channel",
        "start",
        "end",
        "spend_delta",
        "kpi_delta"
      ],
      "title": "LiftTest",
      "type": "object"
    },
    "MaskBlockSplit": {
      "additionalProperties": false,
      "description": "Hold out random blocks over ``dims`` (block sizes per dim) covering ``fraction``.",
      "properties": {
        "after_step": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Stage the split happens at (a step id or 'raw'); default: end of the stateless prefix",
          "title": "After Step"
        },
        "allow_leakage": {
          "default": false,
          "description": "Downgrade LEAKAGE_RISK to a warning (acknowledged)",
          "title": "Allow Leakage",
          "type": "boolean"
        },
        "block": {
          "patternProperties": {
            "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$": {
              "type": "integer"
            }
          },
          "title": "Block",
          "type": "object"
        },
        "dims": {
          "items": {
            "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
            "type": "string"
          },
          "maxItems": 8,
          "minItems": 1,
          "title": "Dims",
          "type": "array"
        },
        "fraction": {
          "exclusiveMaximum": 1,
          "exclusiveMinimum": 0,
          "title": "Fraction",
          "type": "number"
        },
        "kind": {
          "const": "mask_block",
          "title": "Kind",
          "type": "string"
        },
        "seed": {
          "anyOf": [
            {
              "exclusiveMaximum": 4294967296,
              "minimum": 0,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Seed"
        }
      },
      "required": [
        "kind",
        "dims",
        "fraction"
      ],
      "title": "MaskBlockSplit",
      "type": "object"
    },
    "Metadata": {
      "additionalProperties": false,
      "description": "Identity and labels of a document.",
      "properties": {
        "about": {
          "anyOf": [
            {
              "$ref": "#/$defs/About"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "M3.5: a plain-language About card so others can choose this spec, pipeline or workflow (see mapi_spec.about)"
        },
        "description": {
          "anyOf": [
            {
              "maxLength": 4000,
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Description"
        },
        "labels": {
          "maxProperties": 64,
          "patternProperties": {
            "^[a-z0-9]([a-z0-9_.\\-/]{0,62})$": {
              "maxLength": 63,
              "pattern": "^[A-Za-z0-9_.\\-]*$",
              "type": "string"
            }
          },
          "title": "Labels",
          "type": "object"
        },
        "name": {
          "pattern": "^[a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?$",
          "title": "Name",
          "type": "string"
        },
        "project": {
          "pattern": "^[a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?$",
          "title": "Project",
          "type": "string"
        }
      },
      "required": [
        "name",
        "project"
      ],
      "title": "Metadata",
      "type": "object"
    },
    "ModelBlock": {
      "additionalProperties": false,
      "description": "The model plugin, its settings and fit configuration.\n\n``settings.dim_policies`` is platform-reserved: a mapping ``dim \u2192 policy`` that may only\n*tighten* the plugin's policies. It is removed before plugin settings validation.",
      "properties": {
        "fit": {
          "$ref": "#/$defs/FitConfig"
        },
        "settings": {
          "additionalProperties": {
            "$ref": "#/$defs/JsonValue"
          },
          "title": "Settings",
          "type": "object"
        },
        "use": {
          "description": "Registered id with an optional semver range",
          "examples": [
            "core.resample@^1",
            "mmm.bayesian@^1.3"
          ],
          "pattern": "^(?:(?:t|vetted)/[a-z0-9][a-z0-9-]{0,62}/)?[a-z][a-z0-9_]*(?:\\.[a-z][a-z0-9_]*)+(@[^@]{1,256})?$",
          "title": "Use",
          "type": "string"
        }
      },
      "required": [
        "use"
      ],
      "title": "ModelBlock",
      "type": "object"
    },
    "ModelSpec": {
      "additionalProperties": false,
      "description": "The declarative modelling file.",
      "properties": {
        "apiVersion": {
          "const": "mapi/v1",
          "title": "Apiversion",
          "type": "string"
        },
        "calibration": {
          "anyOf": [
            {
              "$ref": "#/$defs/Calibration"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Business priors and lift tests the model should respect (M3); needs a model whose capabilities declare them"
        },
        "data": {
          "$ref": "#/$defs/DataBlock"
        },
        "evaluate": {
          "$ref": "#/$defs/EvaluateBlock"
        },
        "execution": {
          "$ref": "#/$defs/ExecutionBlock"
        },
        "kind": {
          "const": "ModelSpec",
          "title": "Kind",
          "type": "string"
        },
        "metadata": {
          "$ref": "#/$defs/Metadata"
        },
        "model": {
          "$ref": "#/$defs/ModelBlock"
        },
        "outputs": {
          "$ref": "#/$defs/OutputsBlock"
        },
        "pipeline": {
          "items": {
            "$ref": "#/$defs/StepCall"
          },
          "maxItems": 64,
          "title": "Pipeline",
          "type": "array"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "metadata",
        "data",
        "model"
      ],
      "title": "ModelSpec",
      "type": "object"
    },
    "NodeSelect": {
      "additionalProperties": false,
      "description": "One node a spec reads from a tree dataset (an entry of ``data.nodes``).\n\nIts variables (all, or ``vars``) are merged into the flat pipeline input, renamed\n``prefix + name`` when ``prefix`` is given (so two nodes with the same variable names can\nboth be read). Dims are never renamed: a dim shared by several selected nodes must be\nthe same dim (equal :class:`~mapi_spec.schema.DimSpec`).",
      "properties": {
        "path": {
          "pattern": "^/(?:[A-Za-z_][A-Za-z0-9_.\\-]{0,63}(?:/[A-Za-z_][A-Za-z0-9_.\\-]{0,63}){0,7})?$",
          "title": "Path",
          "type": "string"
        },
        "prefix": {
          "anyOf": [
            {
              "pattern": "^[A-Za-z_][A-Za-z0-9_]{0,31}$",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Prepended to the node's variable names in the flat dataset",
          "title": "Prefix"
        },
        "vars": {
          "anyOf": [
            {
              "items": {
                "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
                "type": "string"
              },
              "maxItems": 4096,
              "minItems": 1,
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Default: every variable of the node",
          "title": "Vars"
        }
      },
      "required": [
        "path"
      ],
      "title": "NodeSelect",
      "type": "object"
    },
    "OutputSelector": {
      "additionalProperties": false,
      "description": "What a score request returns.",
      "properties": {
        "aggregate": {
          "anyOf": [
            {
              "$ref": "#/$defs/Aggregation"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "draws": {
          "default": 0,
          "maximum": 10000,
          "minimum": 0,
          "title": "Draws",
          "type": "integer"
        },
        "kind": {
          "default": "expected",
          "enum": [
            "expected",
            "predictive"
          ],
          "title": "Kind",
          "type": "string"
        },
        "names": {
          "default": "dataset",
          "enum": [
            "dataset",
            "canonical"
          ],
          "title": "Names",
          "type": "string"
        },
        "summary": {
          "anyOf": [
            {
              "items": {
                "type": "string"
              },
              "maxItems": 32,
              "type": "array"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Summaries to return; default depends on representation",
          "title": "Summary"
        },
        "thin_index": {
          "const": "bundle",
          "default": "bundle",
          "title": "Thin Index",
          "type": "string"
        },
        "units": {
          "default": "original",
          "enum": [
            "original",
            "model"
          ],
          "title": "Units",
          "type": "string"
        },
        "vars": {
          "items": {
            "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
            "type": "string"
          },
          "maxItems": 256,
          "title": "Vars",
          "type": "array"
        }
      },
      "title": "OutputSelector",
      "type": "object"
    },
    "OutputsBlock": {
      "additionalProperties": false,
      "properties": {
        "derived": {
          "items": {
            "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
            "type": "string"
          },
          "maxItems": 64,
          "title": "Derived",
          "type": "array"
        },
        "plots": {
          "items": {
            "description": "Registered id with an optional semver range",
            "examples": [
              "core.resample@^1",
              "mmm.bayesian@^1.3"
            ],
            "pattern": "^(?:(?:t|vetted)/[a-z0-9][a-z0-9-]{0,62}/)?[a-z][a-z0-9_]*(?:\\.[a-z][a-z0-9_]*)+(@[^@]{1,256})?$",
            "type": "string"
          },
          "maxItems": 64,
          "title": "Plots",
          "type": "array"
        },
        "ui_draws": {
          "default": 300,
          "maximum": 2000,
          "minimum": 0,
          "title": "Ui Draws",
          "type": "integer"
        }
      },
      "title": "OutputsBlock",
      "type": "object"
    },
    "PosteriorPredictiveKeep": {
      "additionalProperties": false,
      "properties": {
        "thin": {
          "default": 1,
          "maximum": 10000,
          "minimum": 1,
          "title": "Thin",
          "type": "integer"
        }
      },
      "title": "PosteriorPredictiveKeep",
      "type": "object"
    },
    "PriorPredictive": {
      "additionalProperties": false,
      "properties": {
        "draws": {
          "maximum": 100000,
          "minimum": 1,
          "title": "Draws",
          "type": "integer"
        }
      },
      "required": [
        "draws"
      ],
      "title": "PriorPredictive",
      "type": "object"
    },
    "ResourceClass": {
      "description": "Executor resource class. Ordered: ``S < M < L < XL < GPU``.\n\n``GPU`` is the last (highest-rank) member on purpose: a quota whose\n``max_resource_class`` is below it refuses it, and :meth:`next_up` never offers it.",
      "enum": [
        "S",
        "M",
        "L",
        "XL",
        "GPU"
      ],
      "title": "ResourceClass",
      "type": "string"
    },
    "SBC": {
      "additionalProperties": false,
      "description": "Simulation-based calibration: ``n`` simulate\u2192fit\u2192rank runs.",
      "properties": {
        "apiVersion": {
          "const": "mapi/v1",
          "title": "Apiversion",
          "type": "string"
        },
        "base": {
          "description": "Spec revision spec://project/name@rN",
          "pattern": "^spec://([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)/([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)@(r\\d{1,9}|\\d{1,9}|sha256:[0-9a-f]{64})$",
          "title": "Base",
          "type": "string"
        },
        "execution": {
          "anyOf": [
            {
              "$ref": "#/$defs/ExecutionBlock"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "kind": {
          "const": "SBC",
          "title": "Kind",
          "type": "string"
        },
        "metadata": {
          "$ref": "#/$defs/Metadata"
        },
        "n": {
          "maximum": 1000,
          "minimum": 1,
          "title": "N",
          "type": "integer"
        },
        "params": {
          "items": {
            "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
            "type": "string"
          },
          "title": "Params",
          "type": "array"
        },
        "seed": {
          "anyOf": [
            {
              "exclusiveMaximum": 4294967296,
              "minimum": 0,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Seed"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "metadata",
        "base",
        "n"
      ],
      "title": "SBC",
      "type": "object"
    },
    "ScorePolicy": {
      "description": "Which side-table version is used at score time.",
      "enum": [
        "pinned",
        "latest",
        "supplied"
      ],
      "title": "ScorePolicy",
      "type": "string"
    },
    "ScoreRequest": {
      "additionalProperties": false,
      "description": "Score a fitted model with replayed preprocessing.",
      "properties": {
        "apiVersion": {
          "const": "mapi/v1",
          "title": "Apiversion",
          "type": "string"
        },
        "data": {
          "anyOf": [
            {
              "description": "Dataset reference dataset://project/name@version",
              "examples": [
                "dataset://growth/eu_media_daily@latest"
              ],
              "pattern": "^dataset://([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)/([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)(?:@(latest|v\\d{1,9}|\\d{1,9}|sha256:[0-9a-f]{64}))?$",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Data"
        },
        "future_covariates": {
          "anyOf": [
            {
              "$ref": "#/$defs/FutureCovariates"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "M3: how forecasts get future covariates (default: supplied)"
        },
        "horizon": {
          "anyOf": [
            {
              "$ref": "#/$defs/Horizon"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "inputs_stage": {
          "default": "raw",
          "pattern": "^[a-z_][a-z0-9_]{0,62}$",
          "title": "Inputs Stage",
          "type": "string"
        },
        "interventions": {
          "items": {
            "$ref": "#/$defs/Intervention"
          },
          "maxItems": 256,
          "title": "Interventions",
          "type": "array"
        },
        "kind": {
          "const": "ScoreRequest",
          "title": "Kind",
          "type": "string"
        },
        "mode": {
          "default": "predict",
          "enum": [
            "predict",
            "forecast",
            "counterfactual",
            "simulate",
            "filter",
            "evaluate"
          ],
          "title": "Mode",
          "type": "string"
        },
        "model": {
          "description": "endpoint://project/alias or model://project/name@vN",
          "pattern": "(?:^endpoint://([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)/([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)$)|(?:^model://([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)/([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)@(latest|v\\d{1,9}|\\d{1,9})$)",
          "title": "Model",
          "type": "string"
        },
        "output": {
          "$ref": "#/$defs/OutputSelector"
        },
        "scenario": {
          "anyOf": [
            {
              "description": "Dataset reference dataset://project/name@version",
              "examples": [
                "dataset://growth/eu_media_daily@latest"
              ],
              "pattern": "^dataset://([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)/([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)(?:@(latest|v\\d{1,9}|\\d{1,9}|sha256:[0-9a-f]{64}))?$",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Scenario"
        },
        "seed": {
          "anyOf": [
            {
              "exclusiveMaximum": 4294967296,
              "minimum": 0,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Seed"
        },
        "select": {
          "maxProperties": 64,
          "patternProperties": {
            "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$": {
              "items": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "integer"
                  },
                  {
                    "type": "number"
                  },
                  {
                    "type": "boolean"
                  }
                ]
              },
              "type": "array"
            }
          },
          "title": "Select",
          "type": "object"
        },
        "side_tables": {
          "maxProperties": 32,
          "patternProperties": {
            "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$": {
              "description": "Dataset reference dataset://project/name@version",
              "examples": [
                "dataset://growth/eu_media_daily@latest"
              ],
              "pattern": "^dataset://([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)/([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)(?:@(latest|v\\d{1,9}|\\d{1,9}|sha256:[0-9a-f]{64}))?$",
              "type": "string"
            }
          },
          "title": "Side Tables",
          "type": "object"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "model"
      ],
      "title": "ScoreRequest",
      "type": "object"
    },
    "ShareBelief": {
      "additionalProperties": false,
      "description": "A share range (for example of the baseline: KPI that happens without any media).",
      "properties": {
        "credibility": {
          "default": 0.8,
          "description": "Probability that the true value lies inside the range (0.8 = 'I am 80% sure')",
          "maximum": 0.99,
          "minimum": 0.5,
          "title": "Credibility",
          "type": "number"
        },
        "share": {
          "maxItems": 2,
          "minItems": 2,
          "prefixItems": [
            {
              "type": "number"
            },
            {
              "type": "number"
            }
          ],
          "title": "Share",
          "type": "array"
        }
      },
      "required": [
        "share"
      ],
      "title": "ShareBelief",
      "type": "object"
    },
    "SideTable": {
      "additionalProperties": false,
      "description": "A small constant dataset (FX rates, holidays ...) used by steps.\n\nA side table that is a tree dataset (M4) reads ONE node, named by ``node``.",
      "properties": {
        "node": {
          "anyOf": [
            {
              "pattern": "^/(?:[A-Za-z_][A-Za-z0-9_.\\-]{0,63}(?:/[A-Za-z_][A-Za-z0-9_.\\-]{0,63}){0,7})?$",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "M4: the node of a tree dataset to read (needed when the table is a tree)",
          "title": "Node"
        },
        "ref": {
          "description": "Dataset reference dataset://project/name@version",
          "examples": [
            "dataset://growth/eu_media_daily@latest"
          ],
          "pattern": "^dataset://([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)/([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)(?:@(latest|v\\d{1,9}|\\d{1,9}|sha256:[0-9a-f]{64}))?$",
          "title": "Ref",
          "type": "string"
        },
        "score_policy": {
          "$ref": "#/$defs/ScorePolicy",
          "default": "pinned"
        }
      },
      "required": [
        "ref"
      ],
      "title": "SideTable",
      "type": "object"
    },
    "StepCall": {
      "additionalProperties": false,
      "description": "One pipeline step: ``{id, use: core.resample@^1, with: {...settings}}``.",
      "properties": {
        "id": {
          "pattern": "^[a-z_][a-z0-9_]{0,62}$",
          "title": "Id",
          "type": "string"
        },
        "use": {
          "description": "Registered id with an optional semver range",
          "examples": [
            "core.resample@^1",
            "mmm.bayesian@^1.3"
          ],
          "pattern": "^(?:(?:t|vetted)/[a-z0-9][a-z0-9-]{0,62}/)?[a-z][a-z0-9_]*(?:\\.[a-z][a-z0-9_]*)+(@[^@]{1,256})?$",
          "title": "Use",
          "type": "string"
        },
        "with": {
          "additionalProperties": {
            "$ref": "#/$defs/JsonValue"
          },
          "title": "With",
          "type": "object"
        }
      },
      "required": [
        "id",
        "use"
      ],
      "title": "StepCall",
      "type": "object"
    },
    "StratifiedSplit": {
      "additionalProperties": false,
      "description": "Hold out a random ``fraction`` of the rows along ``dim`` in each level of ``by`` (the\nclass label; v0.14). A level with one row stays in training.",
      "properties": {
        "after_step": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Stage the split happens at (a step id or 'raw'); default: end of the stateless prefix",
          "title": "After Step"
        },
        "allow_leakage": {
          "default": false,
          "description": "Downgrade LEAKAGE_RISK to a warning (acknowledged)",
          "title": "Allow Leakage",
          "type": "boolean"
        },
        "by": {
          "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
          "title": "By",
          "type": "string"
        },
        "dim": {
          "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
          "title": "Dim",
          "type": "string"
        },
        "fraction": {
          "exclusiveMaximum": 1,
          "exclusiveMinimum": 0,
          "title": "Fraction",
          "type": "number"
        },
        "kind": {
          "const": "stratified",
          "title": "Kind",
          "type": "string"
        },
        "seed": {
          "anyOf": [
            {
              "exclusiveMaximum": 4294967296,
              "minimum": 0,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Seed"
        }
      },
      "required": [
        "kind",
        "dim",
        "by",
        "fraction"
      ],
      "title": "StratifiedSplit",
      "type": "object"
    },
    "Sweep": {
      "additionalProperties": false,
      "description": "A grid over spec paths (JSON pointers) of a base revision, compared by a metric.\n\nRetired in v0.14: stored documents still load; use a workflow with a search.grid node.\nThe server refuses new Sweep documents.",
      "properties": {
        "apiVersion": {
          "const": "mapi/v1",
          "title": "Apiversion",
          "type": "string"
        },
        "base": {
          "description": "Spec revision spec://project/name@rN",
          "pattern": "^spec://([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)/([a-z0-9](?:[a-z0-9_-]{0,126}[a-z0-9])?)@(r\\d{1,9}|\\d{1,9}|sha256:[0-9a-f]{64})$",
          "title": "Base",
          "type": "string"
        },
        "compare_by": {
          "pattern": "^[a-z][a-z0-9_]{0,63}$",
          "title": "Compare By",
          "type": "string"
        },
        "execution": {
          "anyOf": [
            {
              "$ref": "#/$defs/ExecutionBlock"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "grid": {
          "additionalProperties": {
            "items": {
              "$ref": "#/$defs/JsonValue"
            },
            "type": "array"
          },
          "maxProperties": 16,
          "minProperties": 1,
          "title": "Grid",
          "type": "object"
        },
        "kind": {
          "const": "Sweep",
          "title": "Kind",
          "type": "string"
        },
        "max_parallel": {
          "anyOf": [
            {
              "maximum": 1000,
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Max Parallel"
        },
        "metadata": {
          "$ref": "#/$defs/Metadata"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "metadata",
        "base",
        "grid",
        "compare_by"
      ],
      "title": "Sweep",
      "type": "object"
    },
    "TimeHoldoutSplit": {
      "additionalProperties": false,
      "description": "Hold out the end of an ordered dim: ``last`` periods, a ``fraction`` or ``after`` a coord.",
      "properties": {
        "after": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "integer"
            },
            {
              "type": "number"
            },
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "After"
        },
        "after_step": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Stage the split happens at (a step id or 'raw'); default: end of the stateless prefix",
          "title": "After Step"
        },
        "allow_leakage": {
          "default": false,
          "description": "Downgrade LEAKAGE_RISK to a warning (acknowledged)",
          "title": "Allow Leakage",
          "type": "boolean"
        },
        "dim": {
          "pattern": "^[A-Za-z_][A-Za-z0-9_.\\-]{0,127}$",
          "title": "Dim",
          "type": "string"
        },
        "fraction": {
          "anyOf": [
            {
              "exclusiveMaximum": 1,
              "exclusiveMinimum": 0,
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Fraction"
        },
        "kind": {
          "const": "time_holdout",
          "title": "Kind",
          "type": "string"
        },
        "last": {
          "anyOf": [
            {
              "minimum": 1,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Last"
        }
      },
      "required": [
        "kind",
        "dim"
      ],
      "title": "TimeHoldoutSplit",
      "type": "object"
    },
    "TypicalRuntime": {
      "description": "Rough wall-clock time on typical data (``S`` resource class).",
      "enum": [
        "instant",
        "seconds",
        "minutes",
        "long"
      ],
      "title": "TypicalRuntime",
      "type": "string"
    }
  },
  "$id": "https://schemas.mapi.dev/v1/document.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "discriminator": {
    "mapping": {
      "Backtest": "#/$defs/Backtest",
      "Campaign": "#/$defs/Campaign",
      "ModelSpec": "#/$defs/ModelSpec",
      "SBC": "#/$defs/SBC",
      "ScoreRequest": "#/$defs/ScoreRequest",
      "Sweep": "#/$defs/Sweep"
    },
    "propertyName": "kind"
  },
  "oneOf": [
    {
      "$ref": "#/$defs/ModelSpec"
    },
    {
      "$ref": "#/$defs/ScoreRequest"
    },
    {
      "$ref": "#/$defs/Sweep"
    },
    {
      "$ref": "#/$defs/Backtest"
    },
    {
      "$ref": "#/$defs/SBC"
    },
    {
      "$ref": "#/$defs/Campaign"
    }
  ],
  "x-mapi-contract-version": "0.2"
}
