{
  "$defs": {
    "ReaderSpec": {
      "additionalProperties": false,
      "properties": {
        "fn": {
          "enum": [
            "read_csv",
            "read_excel",
            "read_parquet",
            "read_catalogue"
          ],
          "title": "Fn",
          "type": "string"
        },
        "kwargs": {
          "additionalProperties": true,
          "description": "Reader keyword arguments, tagged JSON (no path).",
          "title": "Kwargs",
          "type": "object"
        },
        "replayable": {
          "default": true,
          "title": "Replayable",
          "type": "boolean"
        }
      },
      "required": [
        "fn"
      ],
      "title": "ReaderSpec",
      "type": "object"
    },
    "RecipeCell": {
      "additionalProperties": false,
      "properties": {
        "execution_count": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Execution Count"
        },
        "frames_changed": {
          "items": {
            "type": "string"
          },
          "title": "Frames Changed",
          "type": "array"
        },
        "order": {
          "title": "Order",
          "type": "integer"
        },
        "source": {
          "title": "Source",
          "type": "string"
        }
      },
      "required": [
        "order",
        "source"
      ],
      "title": "RecipeCell",
      "type": "object"
    },
    "RecipeEnvironment": {
      "additionalProperties": false,
      "properties": {
        "numpy": {
          "title": "Numpy",
          "type": "string"
        },
        "pandas": {
          "title": "Pandas",
          "type": "string"
        },
        "platform": {
          "title": "Platform",
          "type": "string"
        },
        "python": {
          "title": "Python",
          "type": "string"
        },
        "ump_recipe": {
          "title": "Ump Recipe",
          "type": "string"
        }
      },
      "required": [
        "python",
        "pandas",
        "numpy",
        "ump_recipe",
        "platform"
      ],
      "title": "RecipeEnvironment",
      "type": "object"
    },
    "RecipeInput": {
      "additionalProperties": false,
      "properties": {
        "catalogue_fingerprint": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "The catalogue's rule (ump_spec.rules.canonical_rows_fingerprint, basis canonical_rows) over the frame as read, cells as plain JSON values; column and row order free. apps/data matches inputs to connected datasets by it.",
          "title": "Catalogue Fingerprint"
        },
        "columns": {
          "additionalProperties": {
            "type": "string"
          },
          "description": "Column name to pandas dtype.",
          "title": "Columns",
          "type": "object"
        },
        "copy_policy": {
          "anyOf": [
            {
              "enum": [
                "allowed",
                "transient_only",
                "aggregates_only"
              ],
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Copy Policy"
        },
        "dataset_id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Dataset Id"
        },
        "fingerprint": {
          "description": "Canonical-rows fingerprint of the frame as read (see fingerprint_basis).",
          "title": "Fingerprint",
          "type": "string"
        },
        "fingerprint_basis": {
          "default": "canonical_rows/ump_recipe-2",
          "title": "Fingerprint Basis",
          "type": "string"
        },
        "fingerprint_seen": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "fetch_record.fingerprint_seen from apps/data when read from the catalogue (blob hash for stored datasets, canonical rows of the raw rows for connected ones).",
          "title": "Fingerprint Seen"
        },
        "input_id": {
          "description": "Also the frame id steps use to refer to this input.",
          "title": "Input Id",
          "type": "string"
        },
        "name": {
          "title": "Name",
          "type": "string"
        },
        "path_basename": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Path Basename"
        },
        "reader": {
          "anyOf": [
            {
              "$ref": "#/$defs/ReaderSpec"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "rows": {
          "title": "Rows",
          "type": "integer"
        },
        "sha256": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "sha256 hex of the file bytes (stored catalogue datasets: blob hash).",
          "title": "Sha256"
        },
        "source": {
          "enum": [
            "file",
            "catalogue",
            "in_memory"
          ],
          "title": "Source",
          "type": "string"
        }
      },
      "required": [
        "input_id",
        "name",
        "source",
        "fingerprint",
        "rows",
        "columns"
      ],
      "title": "RecipeInput",
      "type": "object"
    },
    "RecipeNote": {
      "additionalProperties": false,
      "properties": {
        "cells": {
          "description": "Notebook execution counts the note is about.",
          "items": {
            "type": "integer"
          },
          "title": "Cells",
          "type": "array"
        },
        "code": {
          "enum": [
            "RECIPE_PARTIAL",
            "RECIPE_UNVERIFIED",
            "RECIPE_NOT_REPRODUCED",
            "RECIPE_OUTPUT_MISMATCH",
            "UNCATALOGUED_INPUT",
            "TRANSIENT_DATA"
          ],
          "title": "Code",
          "type": "string"
        },
        "message": {
          "title": "Message",
          "type": "string"
        },
        "severity": {
          "enum": [
            "info",
            "warn"
          ],
          "title": "Severity",
          "type": "string"
        },
        "step_id": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Step Id"
        }
      },
      "required": [
        "code",
        "severity",
        "message"
      ],
      "title": "RecipeNote",
      "type": "object"
    },
    "RecipeOutput": {
      "additionalProperties": false,
      "properties": {
        "columns": {
          "additionalProperties": {
            "type": "string"
          },
          "title": "Columns",
          "type": "object"
        },
        "fingerprint": {
          "description": "Canonical-rows fingerprint of the file as written and read back.",
          "title": "Fingerprint",
          "type": "string"
        },
        "fingerprint_basis": {
          "default": "canonical_rows/ump_recipe-2",
          "title": "Fingerprint Basis",
          "type": "string"
        },
        "format": {
          "default": "csv",
          "enum": [
            "csv",
            "parquet"
          ],
          "title": "Format",
          "type": "string"
        },
        "frame_id": {
          "title": "Frame Id",
          "type": "string"
        },
        "index_written": {
          "default": false,
          "title": "Index Written",
          "type": "boolean"
        },
        "path_basename": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Path Basename"
        },
        "rows": {
          "title": "Rows",
          "type": "integer"
        },
        "rows_written": {
          "default": true,
          "title": "Rows Written",
          "type": "boolean"
        },
        "sha256": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "sha256 hex of the file as written; null when rows were not written.",
          "title": "Sha256"
        }
      },
      "required": [
        "frame_id",
        "fingerprint",
        "rows",
        "columns"
      ],
      "title": "RecipeOutput",
      "type": "object"
    },
    "RecipeStep": {
      "additionalProperties": false,
      "properties": {
        "args": {
          "additionalProperties": true,
          "description": "Tagged JSON: frames as {'__frame__': id}, series expressions as {'__expr__': ...}.",
          "title": "Args",
          "type": "object"
        },
        "cell": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Notebook execution count when the step ran.",
          "title": "Cell"
        },
        "code": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Code"
        },
        "code_sha256": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Code Sha256"
        },
        "columns_added": {
          "items": {
            "type": "string"
          },
          "title": "Columns Added",
          "type": "array"
        },
        "columns_removed": {
          "items": {
            "type": "string"
          },
          "title": "Columns Removed",
          "type": "array"
        },
        "dtype_changes": {
          "additionalProperties": {
            "type": "string"
          },
          "title": "Dtype Changes",
          "type": "object"
        },
        "fingerprint": {
          "description": "In-memory hash of this step's output (basis memory_hash/ump_recipe-1: values, column and index names, shape); replay compares it with the replayed object.",
          "title": "Fingerprint",
          "type": "string"
        },
        "inputs": {
          "description": "Frame ids read by this step; the first is 'self'.",
          "items": {
            "type": "string"
          },
          "title": "Inputs",
          "type": "array"
        },
        "kind": {
          "enum": [
            "named",
            "verb",
            "cell_edit"
          ],
          "title": "Kind",
          "type": "string"
        },
        "note": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Note"
        },
        "op": {
          "description": "Method name, 'loc.__setitem__', 'groupby.sum', 'call:pandas.concat', a named step's function name, or 'unrecorded_change'.",
          "title": "Op",
          "type": "string"
        },
        "output": {
          "title": "Output",
          "type": "string"
        },
        "output_kind": {
          "default": "frame",
          "enum": [
            "frame",
            "series"
          ],
          "title": "Output Kind",
          "type": "string"
        },
        "replayable": {
          "default": true,
          "title": "Replayable",
          "type": "boolean"
        },
        "rows_after": {
          "title": "Rows After",
          "type": "integer"
        },
        "rows_before": {
          "anyOf": [
            {
              "type": "integer"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Rows Before"
        },
        "step_id": {
          "title": "Step Id",
          "type": "string"
        }
      },
      "required": [
        "step_id",
        "kind",
        "op",
        "output",
        "rows_after",
        "fingerprint"
      ],
      "title": "RecipeStep",
      "type": "object"
    },
    "RecipeVerification": {
      "additionalProperties": false,
      "properties": {
        "checked_at": {
          "anyOf": [
            {
              "format": "date-time",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Checked At"
        },
        "checked_by": {
          "anyOf": [
            {
              "const": "self",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Checked By"
        },
        "first_divergent_step": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "First Divergent Step"
        },
        "message": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Message"
        },
        "status": {
          "default": "not_checked",
          "enum": [
            "not_checked",
            "reproduced",
            "not_reproduced",
            "not_replayable",
            "inputs_missing"
          ],
          "title": "Status",
          "type": "string"
        }
      },
      "title": "RecipeVerification",
      "type": "object"
    }
  },
  "$id": "https://schemas.ump.dev/v1/transform-recipe.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false,
  "description": "``<output>.recipe.json``: inputs by hash, steps, notebook cells, the output's fingerprint and the\nanalyst's own replay check.",
  "properties": {
    "author": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Author"
    },
    "capture": {
      "default": "full",
      "enum": [
        "full",
        "partial"
      ],
      "title": "Capture",
      "type": "string"
    },
    "cells": {
      "items": {
        "$ref": "#/$defs/RecipeCell"
      },
      "title": "Cells",
      "type": "array"
    },
    "cells_included": {
      "default": true,
      "title": "Cells Included",
      "type": "boolean"
    },
    "created_at": {
      "format": "date-time",
      "title": "Created At",
      "type": "string"
    },
    "environment": {
      "$ref": "#/$defs/RecipeEnvironment"
    },
    "inputs": {
      "items": {
        "$ref": "#/$defs/RecipeInput"
      },
      "title": "Inputs",
      "type": "array"
    },
    "notes": {
      "items": {
        "$ref": "#/$defs/RecipeNote"
      },
      "title": "Notes",
      "type": "array"
    },
    "output": {
      "$ref": "#/$defs/RecipeOutput"
    },
    "recipe_id": {
      "title": "Recipe Id",
      "type": "string"
    },
    "schema_version": {
      "const": "ump.transform_recipe/0.1",
      "default": "ump.transform_recipe/0.1",
      "title": "Schema Version",
      "type": "string"
    },
    "steps": {
      "items": {
        "$ref": "#/$defs/RecipeStep"
      },
      "title": "Steps",
      "type": "array"
    },
    "title": {
      "title": "Title",
      "type": "string"
    },
    "verification": {
      "$ref": "#/$defs/RecipeVerification"
    }
  },
  "required": [
    "recipe_id",
    "title",
    "created_at",
    "inputs",
    "steps",
    "output",
    "environment"
  ],
  "title": "TransformRecipe",
  "type": "object"
}
