{
  "$id": "https://opendatafabric.org/schemas/tasks/v1alpha1/TaskSpec",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "An individual work item to be executed as part of a flow.",
  "$defs": {
    "Ingest": {
      "description": "Fetches data from a source and appends it to a dataset.",
      "type": "object",
      "required": [
        "source"
      ],
      "properties": {
        "name": {
          "type": "string",
          "description": "An alias for the task used to refer to it in flows and access the results"
        },
        "target": {
          "$ref": "https://opendatafabric.org/schemas/datasets/v1alpha1/DatasetHandle",
          "description": "Reference to the dataset to ingest into. Defaults to the flow-level target when omitted.",
          "unevaluatedProperties": false
        },
        "serviceAccount": {
          "$ref": "https://opendatafabric.org/schemas/auth/v1alpha1/PrincipalHandle",
          "unevaluatedProperties": false,
          "description": "Service account whose permissions the task executes with. Must be an account of service account type. Defaults to the service account of the run when omitted."
        },
        "onNoOp": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/NoOpBehavior",
          "unevaluatedProperties": false,
          "default": "Continue",
          "description": "How the flow run proceeds when this task finishes with a `NoOp` outcome: `Continue` executes the next task, while `Break` finishes the flow run early without an error."
        },
        "onFailure": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/FailureBehavior",
          "unevaluatedProperties": false,
          "default": "Fail",
          "description": "How the flow run proceeds when this task finishes with a `Failed` outcome: `Fail` finishes the flow run with an error, while `Continue` executes the next task."
        },
        "source": {
          "$ref": "https://opendatafabric.org/schemas/resources/v1alpha1/ResourceHandle",
          "description": "Reference to the source resource that defines how to fetch data.",
          "unevaluatedProperties": false
        },
        "targetRecordsPerSlice": {
          "type": "integer",
          "format": "uint64",
          "description": "Target number of records to ingest per data slice."
        }
      }
    },
    "Transform": {
      "description": "Executes transformation of data defined in a derivative dataset.",
      "type": "object",
      "required": [],
      "properties": {
        "name": {
          "type": "string",
          "description": "An alias for the task used to refer to it in flows and access the results"
        },
        "target": {
          "$ref": "https://opendatafabric.org/schemas/datasets/v1alpha1/DatasetHandle",
          "description": "Reference to the derivative dataset that defines how to transform data.",
          "unevaluatedProperties": false
        },
        "serviceAccount": {
          "$ref": "https://opendatafabric.org/schemas/auth/v1alpha1/PrincipalHandle",
          "unevaluatedProperties": false,
          "description": "Service account whose permissions the task executes with. Must be an account of service account type. Defaults to the service account of the run when omitted."
        },
        "onNoOp": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/NoOpBehavior",
          "unevaluatedProperties": false,
          "default": "Continue",
          "description": "How the flow run proceeds when this task finishes with a `NoOp` outcome: `Continue` executes the next task, while `Break` finishes the flow run early without an error."
        },
        "onFailure": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/FailureBehavior",
          "unevaluatedProperties": false,
          "default": "Fail",
          "description": "How the flow run proceeds when this task finishes with a `Failed` outcome: `Fail` finishes the flow run with an error, while `Continue` executes the next task."
        }
      }
    },
    "SyncFrom": {
      "description": "Pulls new blocks from a remote dataset into a local dataset.",
      "type": "object",
      "required": [
        "source"
      ],
      "properties": {
        "name": {
          "type": "string",
          "description": "An alias for the task used to refer to it in flows and access the results"
        },
        "target": {
          "$ref": "https://opendatafabric.org/schemas/datasets/v1alpha1/DatasetHandle",
          "description": "Reference to the local dataset to pull into. Defaults to the flow-level target when omitted.",
          "unevaluatedProperties": false
        },
        "serviceAccount": {
          "$ref": "https://opendatafabric.org/schemas/auth/v1alpha1/PrincipalHandle",
          "unevaluatedProperties": false,
          "description": "Service account whose permissions the task executes with. Must be an account of service account type. Defaults to the service account of the run when omitted."
        },
        "onNoOp": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/NoOpBehavior",
          "unevaluatedProperties": false,
          "default": "Continue",
          "description": "How the flow run proceeds when this task finishes with a `NoOp` outcome: `Continue` executes the next task, while `Break` finishes the flow run early without an error."
        },
        "onFailure": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/FailureBehavior",
          "unevaluatedProperties": false,
          "default": "Fail",
          "description": "How the flow run proceeds when this task finishes with a `Failed` outcome: `Fail` finishes the flow run with an error, while `Continue` executes the next task."
        },
        "source": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/SyncEndpoint",
          "description": "Remote dataset to pull from.",
          "unevaluatedProperties": false
        },
        "force": {
          "type": "boolean",
          "default": false,
          "description": "Overwrite the local dataset even if its history has diverged from the source."
        }
      }
    },
    "SyncTo": {
      "description": "Pushes new blocks of a local dataset to a remote dataset.",
      "type": "object",
      "required": [
        "destination"
      ],
      "properties": {
        "name": {
          "type": "string",
          "description": "An alias for the task used to refer to it in flows and access the results"
        },
        "target": {
          "$ref": "https://opendatafabric.org/schemas/datasets/v1alpha1/DatasetHandle",
          "description": "Reference to the local dataset to push. Defaults to the flow-level target when omitted.",
          "unevaluatedProperties": false
        },
        "serviceAccount": {
          "$ref": "https://opendatafabric.org/schemas/auth/v1alpha1/PrincipalHandle",
          "unevaluatedProperties": false,
          "description": "Service account whose permissions the task executes with. Must be an account of service account type. Defaults to the service account of the run when omitted."
        },
        "onNoOp": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/NoOpBehavior",
          "unevaluatedProperties": false,
          "default": "Continue",
          "description": "How the flow run proceeds when this task finishes with a `NoOp` outcome: `Continue` executes the next task, while `Break` finishes the flow run early without an error."
        },
        "onFailure": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/FailureBehavior",
          "unevaluatedProperties": false,
          "default": "Fail",
          "description": "How the flow run proceeds when this task finishes with a `Failed` outcome: `Fail` finishes the flow run with an error, while `Continue` executes the next task."
        },
        "destination": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/SyncEndpoint",
          "description": "Remote dataset to push to.",
          "unevaluatedProperties": false
        },
        "force": {
          "type": "boolean",
          "default": false,
          "description": "Overwrite the remote dataset even if its history has diverged from the local one."
        },
        "createIfNotExists": {
          "type": "boolean",
          "default": true,
          "description": "Create the remote dataset if it does not exist."
        }
      }
    },
    "Compaction": {
      "description": "Compacts data files in matching datasets to improve query performance.",
      "type": "object",
      "required": [],
      "properties": {
        "name": {
          "type": "string",
          "description": "An alias for the task used to refer to it in flows and access the results"
        },
        "target": {
          "$ref": "https://opendatafabric.org/schemas/datasets/v1alpha1/DatasetHandle",
          "description": "Reference to the dataset to compact. Defaults to the flow-level target when omitted.",
          "unevaluatedProperties": false
        },
        "serviceAccount": {
          "$ref": "https://opendatafabric.org/schemas/auth/v1alpha1/PrincipalHandle",
          "unevaluatedProperties": false,
          "description": "Service account whose permissions the task executes with. Must be an account of service account type. Defaults to the service account of the run when omitted."
        },
        "onNoOp": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/NoOpBehavior",
          "unevaluatedProperties": false,
          "default": "Continue",
          "description": "How the flow run proceeds when this task finishes with a `NoOp` outcome: `Continue` executes the next task, while `Break` finishes the flow run early without an error."
        },
        "onFailure": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/FailureBehavior",
          "unevaluatedProperties": false,
          "default": "Fail",
          "description": "How the flow run proceeds when this task finishes with a `Failed` outcome: `Fail` finishes the flow run with an error, while `Continue` executes the next task."
        },
        "maxSliceSize": {
          "type": "string",
          "format": "byte-size",
          "description": "Target maximum size of each compacted data slice e.g. `100MiB`."
        },
        "maxSliceRecords": {
          "type": "integer",
          "format": "uint64",
          "description": "Target maximum number of records per compacted data slice."
        }
      }
    },
    "Reset": {
      "description": "Moves a block reference of a dataset to an earlier block, discarding the history that follows it.",
      "type": "object",
      "required": [],
      "properties": {
        "name": {
          "type": "string",
          "description": "An alias for the task used to refer to it in flows and access the results"
        },
        "target": {
          "$ref": "https://opendatafabric.org/schemas/datasets/v1alpha1/DatasetHandle",
          "description": "Reference to the dataset to reset. Defaults to the flow-level target when omitted.",
          "unevaluatedProperties": false
        },
        "serviceAccount": {
          "$ref": "https://opendatafabric.org/schemas/auth/v1alpha1/PrincipalHandle",
          "unevaluatedProperties": false,
          "description": "Service account whose permissions the task executes with. Must be an account of service account type. Defaults to the service account of the run when omitted."
        },
        "onNoOp": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/NoOpBehavior",
          "unevaluatedProperties": false,
          "default": "Continue",
          "description": "How the flow run proceeds when this task finishes with a `NoOp` outcome: `Continue` executes the next task, while `Break` finishes the flow run early without an error."
        },
        "onFailure": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/FailureBehavior",
          "unevaluatedProperties": false,
          "default": "Fail",
          "description": "How the flow run proceeds when this task finishes with a `Failed` outcome: `Fail` finishes the flow run with an error, while `Continue` executes the next task."
        },
        "ref": {
          "type": "string",
          "default": "head",
          "description": "Name of the block reference to reset."
        },
        "newBlockHash": {
          "type": "string",
          "format": "multihash",
          "description": "Hash of the block the reference will point to. Defaults to the `Seed` block when omitted."
        },
        "oldBlockHash": {
          "type": "string",
          "format": "multihash",
          "description": "Expected hash of the block the reference currently points to. When specified, the task fails if the reference has moved, protecting against concurrent updates."
        }
      }
    },
    "GarbageCollection": {
      "description": "Removes unreferenced data files from matching datasets.",
      "type": "object",
      "required": [],
      "properties": {
        "name": {
          "type": "string",
          "description": "An alias for the task used to refer to it in flows and access the results"
        },
        "target": {
          "$ref": "https://opendatafabric.org/schemas/datasets/v1alpha1/DatasetHandle",
          "description": "Reference to the dataset to collect garbage from. Defaults to the flow-level target when omitted.",
          "unevaluatedProperties": false
        },
        "serviceAccount": {
          "$ref": "https://opendatafabric.org/schemas/auth/v1alpha1/PrincipalHandle",
          "unevaluatedProperties": false,
          "description": "Service account whose permissions the task executes with. Must be an account of service account type. Defaults to the service account of the run when omitted."
        },
        "onNoOp": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/NoOpBehavior",
          "unevaluatedProperties": false,
          "default": "Continue",
          "description": "How the flow run proceeds when this task finishes with a `NoOp` outcome: `Continue` executes the next task, while `Break` finishes the flow run early without an error."
        },
        "onFailure": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/FailureBehavior",
          "unevaluatedProperties": false,
          "default": "Fail",
          "description": "How the flow run proceeds when this task finishes with a `Failed` outcome: `Fail` finishes the flow run with an error, while `Continue` executes the next task."
        }
      }
    },
    "Verify": {
      "description": "Checks dataset metadata for integrity.",
      "type": "object",
      "required": [],
      "properties": {
        "name": {
          "type": "string",
          "description": "An alias for the task used to refer to it in flows and access the results"
        },
        "target": {
          "$ref": "https://opendatafabric.org/schemas/datasets/v1alpha1/DatasetHandle",
          "description": "Reference to the dataset to verify. Defaults to the flow-level target when omitted.",
          "unevaluatedProperties": false
        },
        "serviceAccount": {
          "$ref": "https://opendatafabric.org/schemas/auth/v1alpha1/PrincipalHandle",
          "unevaluatedProperties": false,
          "description": "Service account whose permissions the task executes with. Must be an account of service account type. Defaults to the service account of the run when omitted."
        },
        "onNoOp": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/NoOpBehavior",
          "unevaluatedProperties": false,
          "default": "Continue",
          "description": "How the flow run proceeds when this task finishes with a `NoOp` outcome: `Continue` executes the next task, while `Break` finishes the flow run early without an error."
        },
        "onFailure": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/FailureBehavior",
          "unevaluatedProperties": false,
          "default": "Fail",
          "description": "How the flow run proceeds when this task finishes with a `Failed` outcome: `Fail` finishes the flow run with an error, while `Continue` executes the next task."
        },
        "replayTransform": {
          "type": "boolean",
          "description": "If true, re-executes transformations on derivative datasets to verify reproducibility."
        }
      }
    },
    "WebhookCall": {
      "description": "Dispatches a certain payload to a specific `WebhookEndpoint`.",
      "type": "object",
      "required": [
        "endpoint"
      ],
      "properties": {
        "name": {
          "type": "string",
          "description": "An alias for the task used to refer to it in flows and access the results"
        },
        "serviceAccount": {
          "$ref": "https://opendatafabric.org/schemas/auth/v1alpha1/PrincipalHandle",
          "unevaluatedProperties": false,
          "description": "Service account whose permissions the task executes with. Must be an account of service account type. Defaults to the service account of the run when omitted."
        },
        "onNoOp": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/NoOpBehavior",
          "unevaluatedProperties": false,
          "default": "Continue",
          "description": "How the flow run proceeds when this task finishes with a `NoOp` outcome: `Continue` executes the next task, while `Break` finishes the flow run early without an error."
        },
        "onFailure": {
          "$ref": "https://opendatafabric.org/schemas/tasks/v1alpha1/FailureBehavior",
          "unevaluatedProperties": false,
          "default": "Fail",
          "description": "How the flow run proceeds when this task finishes with a `Failed` outcome: `Fail` finishes the flow run with an error, while `Continue` executes the next task."
        },
        "endpoint": {
          "$ref": "https://opendatafabric.org/schemas/resources/v1alpha1/ResourceHandle",
          "description": "Reference to the `WebhookEndpoint`.",
          "unevaluatedProperties": false
        },
        "payload": {
          "type": "string",
          "description": "The payload to send. May include templating."
        },
        "retryPolicy": {
          "$ref": "https://opendatafabric.org/schemas/flows/v1alpha1/RetryPolicy",
          "unevaluatedProperties": false,
          "description": "Defines how a webhook should react to failures."
        }
      }
    }
  },
  "oneOf": [
    {
      "allOf": [
        {
          "properties": {
            "kind": {
              "type": "string",
              "const": "Ingest"
            }
          },
          "required": [
            "kind"
          ]
        },
        {
          "$ref": "#/$defs/Ingest"
        }
      ]
    },
    {
      "allOf": [
        {
          "properties": {
            "kind": {
              "type": "string",
              "const": "Transform"
            }
          },
          "required": [
            "kind"
          ]
        },
        {
          "$ref": "#/$defs/Transform"
        }
      ]
    },
    {
      "allOf": [
        {
          "properties": {
            "kind": {
              "type": "string",
              "const": "SyncFrom"
            }
          },
          "required": [
            "kind"
          ]
        },
        {
          "$ref": "#/$defs/SyncFrom"
        }
      ]
    },
    {
      "allOf": [
        {
          "properties": {
            "kind": {
              "type": "string",
              "const": "SyncTo"
            }
          },
          "required": [
            "kind"
          ]
        },
        {
          "$ref": "#/$defs/SyncTo"
        }
      ]
    },
    {
      "allOf": [
        {
          "properties": {
            "kind": {
              "type": "string",
              "const": "Compaction"
            }
          },
          "required": [
            "kind"
          ]
        },
        {
          "$ref": "#/$defs/Compaction"
        }
      ]
    },
    {
      "allOf": [
        {
          "properties": {
            "kind": {
              "type": "string",
              "const": "Reset"
            }
          },
          "required": [
            "kind"
          ]
        },
        {
          "$ref": "#/$defs/Reset"
        }
      ]
    },
    {
      "allOf": [
        {
          "properties": {
            "kind": {
              "type": "string",
              "const": "GarbageCollection"
            }
          },
          "required": [
            "kind"
          ]
        },
        {
          "$ref": "#/$defs/GarbageCollection"
        }
      ]
    },
    {
      "allOf": [
        {
          "properties": {
            "kind": {
              "type": "string",
              "const": "Verify"
            }
          },
          "required": [
            "kind"
          ]
        },
        {
          "$ref": "#/$defs/Verify"
        }
      ]
    },
    {
      "allOf": [
        {
          "properties": {
            "kind": {
              "type": "string",
              "const": "WebhookCall"
            }
          },
          "required": [
            "kind"
          ]
        },
        {
          "$ref": "#/$defs/WebhookCall"
        }
      ]
    }
  ]
}