{
  "$defs": {
    "JsonValue": {},
    "PostPolicy": {
      "additionalProperties": false,
      "description": "A V4 POST policy: multipart form uploads of any key under ``prefix``.\n\nThe uploader posts ``multipart/form-data`` to ``url`` with every entry of ``fields``,\nthen ``key`` (which must start with ``prefix``), then the ``file`` part last. The storage\nservice rejects bodies outside ``content_length_range`` and keys outside the prefix.\n\nA ``create_only`` policy cannot replace an existing object (its signed conditions carry\n``x-goog-if-generation-match: 0``), so the holder can neither overwrite the write-once\nmanifest nor swap an output after it was written.",
      "examples": [
        {
          "content_length_range": [
            0,
            1073741824
          ],
          "expires_at": "2026-10-15T10:30:00Z",
          "fields": {
            "policy": "eyJjb25kaXRpb25zIjpbXX0=",
            "x-goog-algorithm": "GOOG4-HMAC-SHA256",
            "x-goog-credential": "local/20261015/auto/storage/goog4_request",
            "x-goog-date": "20261015T093000Z",
            "x-goog-signature": "abcdef0123"
          },
          "method": "POST",
          "prefix": "t/default/runs/run_01jabc/a1/",
          "url": "http://127.0.0.1:4443/mapi-local-runs"
        }
      ],
      "properties": {
        "content_length_range": {
          "maxItems": 2,
          "minItems": 2,
          "prefixItems": [
            {
              "type": "integer"
            },
            {
              "type": "integer"
            }
          ],
          "title": "Content Length Range",
          "type": "array"
        },
        "create_only": {
          "default": false,
          "title": "Create Only",
          "type": "boolean"
        },
        "expires_at": {
          "format": "date-time",
          "title": "Expires At",
          "type": "string"
        },
        "fields": {
          "additionalProperties": {
            "type": "string"
          },
          "maxProperties": 32,
          "title": "Fields",
          "type": "object"
        },
        "method": {
          "const": "POST",
          "default": "POST",
          "title": "Method",
          "type": "string"
        },
        "prefix": {
          "maxLength": 1024,
          "minLength": 1,
          "title": "Prefix",
          "type": "string"
        },
        "url": {
          "maxLength": 8192,
          "minLength": 8,
          "title": "Url",
          "type": "string"
        }
      },
      "required": [
        "url",
        "prefix",
        "content_length_range",
        "expires_at"
      ],
      "title": "PostPolicy",
      "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"
    },
    "RunKind": {
      "description": "What a run does. ``validate`` is the explicit sandboxed dry-run of a spec.\n\n``sweep``, ``backtest``, ``sbc`` and ``campaign`` are fan-out *parents* (plan \u00a76.2,\nM4): they own child runs and never execute on an executor themselves.",
      "enum": [
        "ingest",
        "describe",
        "validate",
        "fit",
        "score",
        "evaluate",
        "derive",
        "render",
        "optimize",
        "sweep",
        "backtest",
        "sbc",
        "campaign",
        "translate_priors",
        "workflow",
        "workflow_node",
        "explore",
        "governance",
        "inspect"
      ],
      "title": "RunKind",
      "type": "string"
    },
    "RunLimits": {
      "additionalProperties": false,
      "description": "Caps the supervisor enforces (exceeding them is a ``SANDBOX_VIOLATION``).",
      "properties": {
        "log_line_bytes": {
          "default": 4096,
          "maximum": 65536,
          "minimum": 256,
          "title": "Log Line Bytes",
          "type": "integer"
        },
        "log_total_bytes": {
          "default": 20971520,
          "minimum": 0,
          "title": "Log Total Bytes",
          "type": "integer"
        },
        "max_event_bytes": {
          "default": 65536,
          "maximum": 65536,
          "minimum": 1024,
          "title": "Max Event Bytes",
          "type": "integer"
        },
        "max_output_bytes": {
          "description": "Sum of all uploaded output objects",
          "minimum": 0,
          "title": "Max Output Bytes",
          "type": "integer"
        },
        "max_output_objects": {
          "default": 10000,
          "minimum": 1,
          "title": "Max Output Objects",
          "type": "integer"
        },
        "progress_interval_s": {
          "default": 2.0,
          "maximum": 60,
          "minimum": 0.5,
          "title": "Progress Interval S",
          "type": "number"
        },
        "scratch_bytes": {
          "anyOf": [
            {
              "minimum": 0,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "In-memory filesystem budget",
          "title": "Scratch Bytes"
        },
        "tracking": {
          "$ref": "#/$defs/TrackingLimits",
          "description": "Run tracking budgets (v0.11)"
        }
      },
      "required": [
        "max_output_bytes"
      ],
      "title": "RunLimits",
      "type": "object"
    },
    "SignedGet": {
      "additionalProperties": false,
      "description": "A generation-pinned signed GET URL plus the server-computed facts about its object.\n\nThe URL honours HTTP ``Range``, so zarr zip readers can range-read one object. A reader\nverifies ``size``/``crc32c`` after a full download (corruption check only \u2014 integrity is\nenforced by the control plane).",
      "examples": [
        {
          "content_type": "application/zip",
          "crc32c": "4waSgw==",
          "expires_at": "2026-10-15T10:30:00Z",
          "generation": 17,
          "method": "GET",
          "size": 52428800,
          "url": "http://127.0.0.1:4443/download/storage/v1/b/mapi-local-data/o/t%2Fdefault%2Fdatasets%2Fab12%2Fdata.zarr.zip?generation=17&X-Goog-Signature=..."
        }
      ],
      "properties": {
        "content_type": {
          "anyOf": [
            {
              "maxLength": 256,
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Content Type"
        },
        "crc32c": {
          "description": "CRC32C as GCS reports it: base64 of the big-endian 4-byte checksum",
          "examples": [
            "4waSgw=="
          ],
          "pattern": "^[A-Za-z0-9+/]{6}==$",
          "title": "Crc32C",
          "type": "string"
        },
        "expires_at": {
          "format": "date-time",
          "title": "Expires At",
          "type": "string"
        },
        "generation": {
          "minimum": 1,
          "title": "Generation",
          "type": "integer"
        },
        "md5_hash": {
          "anyOf": [
            {
              "description": "MD5 as GCS reports it: base64 of the 16-byte digest",
              "pattern": "^[A-Za-z0-9+/]{22}==$",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Md5 Hash"
        },
        "method": {
          "const": "GET",
          "default": "GET",
          "title": "Method",
          "type": "string"
        },
        "size": {
          "minimum": 0,
          "title": "Size",
          "type": "integer"
        },
        "url": {
          "maxLength": 8192,
          "minLength": 8,
          "title": "Url",
          "type": "string"
        }
      },
      "required": [
        "url",
        "expires_at",
        "generation",
        "size",
        "crc32c"
      ],
      "title": "SignedGet",
      "type": "object"
    },
    "SignedPut": {
      "additionalProperties": false,
      "description": "A signed PUT URL for exactly one object name.\n\n``headers`` must be sent verbatim (they are part of the signature): typically\n``content-type``, ``x-goog-if-generation-match: 0`` (write-once) and\n``x-goog-content-length-range: 0,<max_bytes>``.",
      "examples": [
        {
          "expires_at": "2026-10-15T10:30:00Z",
          "headers": {
            "content-type": "application/json",
            "x-goog-content-length-range": "0,1048576",
            "x-goog-if-generation-match": "0"
          },
          "max_bytes": 1048576,
          "method": "PUT",
          "name": "t/default/runs/run_01jabc/a1/manifest.json",
          "url": "http://127.0.0.1:4443/upload/storage/v1/b/mapi-local-runs/o/t%2Fdefault%2Fruns%2Frun_01jabc%2Fa1%2Fmanifest.json?X-Goog-Signature=..."
        }
      ],
      "properties": {
        "expires_at": {
          "format": "date-time",
          "title": "Expires At",
          "type": "string"
        },
        "headers": {
          "additionalProperties": {
            "type": "string"
          },
          "maxProperties": 32,
          "title": "Headers",
          "type": "object"
        },
        "max_bytes": {
          "anyOf": [
            {
              "minimum": 0,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Max Bytes"
        },
        "method": {
          "const": "PUT",
          "default": "PUT",
          "title": "Method",
          "type": "string"
        },
        "name": {
          "maxLength": 1024,
          "minLength": 1,
          "title": "Name",
          "type": "string"
        },
        "url": {
          "maxLength": 8192,
          "minLength": 8,
          "title": "Url",
          "type": "string"
        }
      },
      "required": [
        "url",
        "name",
        "expires_at"
      ],
      "title": "SignedPut",
      "type": "object"
    },
    "TrackingLimits": {
      "additionalProperties": false,
      "description": "Per-run tracking budgets; the runner, the supervisor and the server enforce them.",
      "properties": {
        "flush_interval_s": {
          "default": 1.0,
          "maximum": 30,
          "minimum": 0.1,
          "title": "Flush Interval S",
          "type": "number"
        },
        "log_bytes": {
          "default": 2097152,
          "minimum": 0,
          "title": "Log Bytes",
          "type": "integer"
        },
        "log_lines": {
          "default": 10000,
          "description": "User (structured) log lines",
          "minimum": 0,
          "title": "Log Lines",
          "type": "integer"
        },
        "media_bytes": {
          "default": 268435456,
          "description": "Sum of the stored media bytes per run (v0.14)",
          "minimum": 0,
          "title": "Media Bytes",
          "type": "integer"
        },
        "media_item_bytes": {
          "default": 8388608,
          "description": "Bytes of one media item (v0.14)",
          "maximum": 8388608,
          "minimum": 1024,
          "title": "Media Item Bytes",
          "type": "integer"
        },
        "media_items": {
          "default": 1000,
          "description": "Distinct media rows per run (v0.14)",
          "minimum": 0,
          "title": "Media Items",
          "type": "integer"
        },
        "metric_points_per_series": {
          "default": 10000,
          "minimum": 1,
          "title": "Metric Points Per Series",
          "type": "integer"
        },
        "metric_points_total": {
          "default": 500000,
          "minimum": 1,
          "title": "Metric Points Total",
          "type": "integer"
        },
        "metric_series": {
          "default": 1000,
          "description": "Distinct (key, labels) series",
          "minimum": 1,
          "title": "Metric Series",
          "type": "integer"
        },
        "params": {
          "default": 5000,
          "minimum": 0,
          "title": "Params",
          "type": "integer"
        },
        "tags": {
          "default": 100,
          "maximum": 100,
          "minimum": 0,
          "title": "Tags",
          "type": "integer"
        },
        "tracking_bytes": {
          "default": 67108864,
          "description": "Hard cap on the bytes of tracking frames; above it the run fails with SANDBOX_VIOLATION",
          "minimum": 1024,
          "title": "Tracking Bytes",
          "type": "integer"
        }
      },
      "title": "TrackingLimits",
      "type": "object"
    }
  },
  "$id": "https://schemas.mapi.dev/v1/runspec.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false,
  "description": "The bootstrap object at ``bootstrap/<nonce>`` (plan \u00a78.1).\n\nWritten by the dispatcher right before the executor call and deleted by the supervisor\nimmediately after reading it. It is the *only* way a run receives URLs and its HMAC key:\nthe environment carries just :class:`RunnerEnv`.",
  "examples": [
    {
      "attempt": 1,
      "catalog_digest": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
      "created_at": "2026-10-15T10:00:00Z",
      "deadline": "2026-10-15T10:45:00Z",
      "hmac_key": "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
      "inputs": {
        "dataset": {
          "crc32c": "4waSgw==",
          "expires_at": "2026-10-15T11:00:00Z",
          "generation": 3,
          "method": "GET",
          "size": 1048576,
          "url": "http://127.0.0.1:4443/download/storage/v1/b/mapi-local-data/o/t%2Fdefault%2Fdatasets%2Fab%2Fdata.zarr.zip?generation=3"
        }
      },
      "kind": "fit",
      "limits": {
        "max_output_bytes": 1000000000,
        "scratch_bytes": 3221225472
      },
      "nonce": "9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f9f",
      "outputs": {
        "artifacts": {
          "content_length_range": [
            0,
            1000000000
          ],
          "expires_at": "2026-10-15T11:00:00Z",
          "fields": {
            "policy": "e30=",
            "x-goog-signature": "00"
          },
          "method": "POST",
          "prefix": "t/default/runs/run_01jabcdefghjkmnpqrstvwxyz0/a1/",
          "url": "http://127.0.0.1:4443/mapi-local-runs"
        },
        "manifest": {
          "expires_at": "2026-10-15T11:00:00Z",
          "headers": {
            "x-goog-if-generation-match": "0"
          },
          "max_bytes": 1048576,
          "method": "PUT",
          "name": "t/default/runs/run_01jabcdefghjkmnpqrstvwxyz0/a1/manifest.json",
          "url": "http://127.0.0.1:4443/upload/storage/v1/b/mapi-local-runs/o?name=t%2Fdefault%2Fruns%2Frun_01jabcdefghjkmnpqrstvwxyz0%2Fa1%2Fmanifest.json"
        }
      },
      "project_id": "default",
      "resource_class": "S",
      "run_id": "run_01jabcdefghjkmnpqrstvwxyz0",
      "schema_version": "mapi.runspec/v1",
      "spec": {
        "apiVersion": "mapi/v1",
        "kind": "ModelSpec"
      },
      "spec_hash": "sha256:abababababababababababababababababababababababababababababababab",
      "tenant_id": "default"
    }
  ],
  "properties": {
    "attempt": {
      "minimum": 1,
      "title": "Attempt",
      "type": "integer"
    },
    "catalog_digest": {
      "pattern": "^sha256:[0-9a-f]{64}$",
      "title": "Catalog Digest",
      "type": "string"
    },
    "checkpoint_prefix": {
      "anyOf": [
        {
          "maxLength": 1024,
          "minLength": 1,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Checkpoint Prefix"
    },
    "created_at": {
      "format": "date-time",
      "title": "Created At",
      "type": "string"
    },
    "deadline": {
      "description": "Hard wall-clock deadline (UTC)",
      "format": "date-time",
      "title": "Deadline",
      "type": "string"
    },
    "hmac_key": {
      "description": "Base64 per-run HMAC-SHA256 key",
      "title": "Hmac Key",
      "type": "string"
    },
    "input_layouts": {
      "description": "M4: the layout of dataset inputs that are not a plain dataset (input name -> 'tree' for a data.tree.zip; v0.15: 'collection' for an image collection, whose manifest.parquet is the input and whose info and packs are the inputs <name>.info and <name>.pack.<i>); absent inputs are 'dataset'",
      "maxProperties": 256,
      "patternProperties": {
        "^[a-z][a-z0-9_.\\-]{0,63}$": {
          "enum": [
            "dataset",
            "tree",
            "collection"
          ],
          "type": "string"
        }
      },
      "title": "Input Layouts",
      "type": "object"
    },
    "inputs": {
      "maxProperties": 256,
      "patternProperties": {
        "^[a-z][a-z0-9_.\\-]{0,63}$": {
          "$ref": "#/$defs/SignedGet"
        }
      },
      "title": "Inputs",
      "type": "object"
    },
    "kind": {
      "$ref": "#/$defs/RunKind"
    },
    "labels": {
      "additionalProperties": {
        "type": "string"
      },
      "maxProperties": 64,
      "title": "Labels",
      "type": "object"
    },
    "limits": {
      "$ref": "#/$defs/RunLimits"
    },
    "media_prefix": {
      "anyOf": [
        {
          "maxLength": 1024,
          "minLength": 1,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "v0.14: where the supervisor uploads logged media (``{run_prefix}media/``)",
      "title": "Media Prefix"
    },
    "nonce": {
      "pattern": "^[0-9a-f]{64}$",
      "title": "Nonce",
      "type": "string"
    },
    "outputs": {
      "maxProperties": 16,
      "patternProperties": {
        "^[a-z][a-z0-9_.\\-]{0,63}$": {
          "discriminator": {
            "mapping": {
              "POST": "#/$defs/PostPolicy",
              "PUT": "#/$defs/SignedPut"
            },
            "propertyName": "method"
          },
          "oneOf": [
            {
              "$ref": "#/$defs/SignedPut"
            },
            {
              "$ref": "#/$defs/PostPolicy"
            }
          ]
        }
      },
      "title": "Outputs",
      "type": "object"
    },
    "project_id": {
      "examples": [
        "default"
      ],
      "pattern": "^[a-z0-9](?:[a-z0-9_-]{0,62}[a-z0-9])?$",
      "title": "Project Id",
      "type": "string"
    },
    "resource_class": {
      "$ref": "#/$defs/ResourceClass"
    },
    "resume": {
      "description": "Checkpoints of the previous attempt",
      "maxProperties": 1024,
      "patternProperties": {
        "^[a-z][a-z0-9_.\\-]{0,63}$": {
          "$ref": "#/$defs/SignedGet"
        }
      },
      "title": "Resume",
      "type": "object"
    },
    "run_id": {
      "pattern": "^[A-Za-z0-9][A-Za-z0-9_.\\-]{0,127}$",
      "title": "Run Id",
      "type": "string"
    },
    "schema_version": {
      "const": "mapi.runspec/v1",
      "default": "mapi.runspec/v1",
      "title": "Schema Version",
      "type": "string"
    },
    "spec": {
      "additionalProperties": {
        "$ref": "#/$defs/JsonValue"
      },
      "description": "Resolved spec JSON (ModelSpec/ScoreRequest/ingest mapping ...)",
      "title": "Spec",
      "type": "object"
    },
    "spec_hash": {
      "pattern": "^sha256:[0-9a-f]{64}$",
      "title": "Spec Hash",
      "type": "string"
    },
    "tenant_id": {
      "examples": [
        "default"
      ],
      "pattern": "^[a-z0-9](?:[a-z0-9_-]{0,62}[a-z0-9])?$",
      "title": "Tenant Id",
      "type": "string"
    }
  },
  "required": [
    "run_id",
    "attempt",
    "nonce",
    "kind",
    "tenant_id",
    "project_id",
    "spec",
    "spec_hash",
    "catalog_digest",
    "outputs",
    "hmac_key",
    "limits",
    "resource_class",
    "deadline",
    "created_at"
  ],
  "title": "RunSpec",
  "type": "object",
  "x-mapi-contract-version": "0.2"
}
