{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://sediment.so/schemas/training-rows/sft-sample/v3.json",
  "title": "SFTSample",
  "description": "One SFT sample.",
  "type": "object",
  "properties": {
    "prompt": {
      "type": "array",
      "items": {
        "anyOf": [
          {
            "$ref": "#/$defs/TrainerTextMessage"
          },
          {
            "anyOf": [
              {
                "$ref": "#/$defs/TrainerAssistantContentMessage"
              },
              {
                "$ref": "#/$defs/TrainerAssistantThinkingMessage"
              },
              {
                "$ref": "#/$defs/TrainerAssistantToolCallMessage"
              }
            ]
          },
          {
            "$ref": "#/$defs/TrainerToolMessage"
          }
        ]
      },
      "description": "The ordered trainer-facing request-context messages."
    },
    "completion": {
      "type": "array",
      "items": {
        "anyOf": [
          {
            "$ref": "#/$defs/TrainerAssistantContentMessage"
          },
          {
            "$ref": "#/$defs/TrainerAssistantThinkingMessage"
          },
          {
            "$ref": "#/$defs/TrainerAssistantToolCallMessage"
          }
        ]
      },
      "description": "The response messages to train on."
    },
    "tools": {
      "type": "array",
      "items": false,
      "description": "Tool definitions available to the trainer. Empty for inference-call schema version 1, which carries no tool-definition field."
    },
    "metadata": {
      "$ref": "#/$defs/SFTMetadata",
      "description": "Sediment evidence excluded from trainer inputs."
    }
  },
  "additionalProperties": false,
  "required": [
    "prompt",
    "completion",
    "tools",
    "metadata"
  ],
  "$defs": {
    "TrainerTextMessage": {
      "type": "object",
      "properties": {
        "role": {
          "enum": [
            "developer",
            "system",
            "user"
          ],
          "type": "string",
          "description": "The trainer-facing message role."
        },
        "content": {
          "type": "string",
          "description": "Plain-text message content."
        }
      },
      "additionalProperties": false,
      "required": [
        "role",
        "content"
      ]
    },
    "TrainerAssistantContentMessage": {
      "type": "object",
      "properties": {
        "role": {
          "const": "assistant",
          "type": "string",
          "description": "The trainer-facing message role."
        },
        "content": {
          "type": "string",
          "description": "Plain-text message content."
        },
        "thinking": {
          "type": "string",
          "description": "Readable assistant reasoning kept outside visible content."
        },
        "tool_calls": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/TrainerToolCall"
          },
          "description": "Structured function calls requested by the assistant."
        }
      },
      "additionalProperties": false,
      "required": [
        "role",
        "content"
      ]
    },
    "TrainerToolCall": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "The tool-call identity used by the matching result."
        },
        "type": {
          "const": "function",
          "type": "string",
          "description": "The fixed `function` tool-call discriminator."
        },
        "function": {
          "$ref": "#/$defs/TrainerFunctionCall",
          "description": "The structured function payload for this tool call."
        }
      },
      "additionalProperties": false,
      "required": [
        "id",
        "type",
        "function"
      ]
    },
    "TrainerFunctionCall": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "The function name associated with this tool call or result."
        },
        "arguments": {
          "type": "object",
          "additionalProperties": {},
          "description": "The exact structured arguments supplied to the function."
        }
      },
      "additionalProperties": false,
      "required": [
        "name",
        "arguments"
      ]
    },
    "TrainerAssistantThinkingMessage": {
      "type": "object",
      "properties": {
        "role": {
          "const": "assistant",
          "type": "string",
          "description": "The trainer-facing message role."
        },
        "thinking": {
          "type": "string",
          "description": "Readable assistant reasoning kept outside visible content."
        },
        "content": {
          "type": "string",
          "description": "Plain-text message content."
        },
        "tool_calls": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/TrainerToolCall"
          },
          "description": "Structured function calls requested by the assistant."
        }
      },
      "additionalProperties": false,
      "required": [
        "role",
        "thinking"
      ]
    },
    "TrainerAssistantToolCallMessage": {
      "type": "object",
      "properties": {
        "role": {
          "const": "assistant",
          "type": "string",
          "description": "The trainer-facing message role."
        },
        "tool_calls": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/TrainerToolCall"
          },
          "description": "Structured function calls requested by the assistant."
        },
        "thinking": {
          "type": "string",
          "description": "Readable assistant reasoning kept outside visible content."
        },
        "content": {
          "type": "string",
          "description": "Plain-text message content."
        }
      },
      "additionalProperties": false,
      "required": [
        "role",
        "tool_calls"
      ]
    },
    "TrainerToolMessage": {
      "type": "object",
      "properties": {
        "role": {
          "const": "tool",
          "type": "string",
          "description": "The trainer-facing message role."
        },
        "name": {
          "type": "string",
          "description": "The function name associated with this tool call or result."
        },
        "tool_call_id": {
          "type": "string",
          "description": "The earlier tool-call id this result answers."
        },
        "content": {
          "type": "string",
          "description": "Plain-text message content."
        }
      },
      "additionalProperties": false,
      "required": [
        "role",
        "name",
        "tool_call_id",
        "content"
      ]
    },
    "SFTMetadata": {
      "type": "object",
      "properties": {
        "org_id": {
          "type": "string",
          "description": "The deployment's tenant id, normalized. Bound to the server."
        },
        "source_model": {
          "type": "string",
          "description": "The model that served the source inference call."
        },
        "completion_id": {
          "type": "string",
          "description": "The inference call that supplied the training target."
        },
        "recipe_id": {
          "enum": [
            "sft_curated",
            "sft_verified"
          ],
          "type": "string",
          "description": "The closed evidence recipe that produced this training row."
        },
        "recipe_version": {
          "const": 1,
          "type": "integer",
          "description": "The version of the evidence recipe; increment it when recipe semantics change."
        },
        "eligibility_source": {
          "enum": [
            "explicit_accept",
            "edit_retention",
            "resolved_ci_pass"
          ],
          "type": "string",
          "description": "The closed evidence source that made this supervised target eligible."
        },
        "label_confidence": {
          "type": "number",
          "description": "Trust in the derived training label, bounded to [0, 1]."
        },
        "ci_reliability": {
          "anyOf": [
            {
              "type": "number"
            },
            {
              "type": "null"
            }
          ],
          "description": "Trust in the resolved CI evidence, separate from the categorical label."
        },
        "provenance": {
          "$ref": "#/$defs/Provenance",
          "description": "The structured provenance for this artifact."
        },
        "split": {
          "enum": [
            "train",
            "eval"
          ],
          "type": "string",
          "description": "Which side of the deterministic eval split this row is on, hashed on `session_id` so a session never straddles both."
        },
        "repository_identity": {
          "anyOf": [
            {
              "$ref": "#/$defs/RepositoryIdentity"
            },
            {
              "type": "null"
            }
          ],
          "description": "Qualified provider, host, and repository ID; null for an unambiguous legacy repository."
        },
        "attribution_source": {
          "anyOf": [
            {
              "enum": [
                "git_notes",
                "jaccard"
              ],
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "The selected target's inferred Attribution method, independent of recipe eligibility."
        },
        "session_commit_observation_ids": {
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^[^\\u0000\\uD800-\\uDFFF]*$"
          },
          "description": "Sorted unique observation IDs for the selected target's exact Session-to-commit edge; empty when absent."
        },
        "schema_id": {
          "const": "https://sediment.so/schemas/training-rows/sft-sample/v3.json",
          "type": "string",
          "description": "The canonical wire-shape contract for this row."
        },
        "schema_version": {
          "const": 3,
          "type": "integer",
          "description": "The positive integer version of the canonical row schema."
        }
      },
      "additionalProperties": false,
      "required": [
        "org_id",
        "source_model",
        "completion_id",
        "recipe_id",
        "recipe_version",
        "eligibility_source",
        "label_confidence",
        "ci_reliability",
        "provenance",
        "split",
        "repository_identity",
        "attribution_source",
        "session_commit_observation_ids",
        "schema_id",
        "schema_version"
      ]
    },
    "Provenance": {
      "type": "object",
      "properties": {
        "policy_version": {
          "type": "string",
          "description": "The derivation implementation policy version."
        },
        "quarantine_revision": {
          "type": "integer",
          "description": "The integer quarantine-log high-water mark used for the derivation."
        },
        "policy_digest": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "description": "SHA-256 of the fully resolved derivation policy when available."
        }
      },
      "additionalProperties": false,
      "required": [
        "policy_version",
        "quarantine_revision",
        "policy_digest"
      ]
    },
    "RepositoryIdentity": {
      "type": "object",
      "properties": {
        "provider": {
          "const": "github",
          "type": "string",
          "description": "The forge provider that assigns the immutable repository ID."
        },
        "host": {
          "type": "string",
          "pattern": "^[^\\u0000\\uD800-\\uDFFF]*$",
          "description": "The lowercase configured forge host."
        },
        "repository_id": {
          "type": "string",
          "pattern": "^[^\\u0000\\uD800-\\uDFFF]*$",
          "description": "Immutable provider repository ID within its forge host."
        }
      },
      "additionalProperties": false,
      "required": [
        "provider",
        "host",
        "repository_id"
      ]
    }
  }
}
