{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://course.example.edu/schemas/trajectory-v1.json",
  "title": "Course trajectory v1: one call per JSONL line",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "schema_version": {
      "const": "1"
    },
    "run": {
      "$ref": "#/$defs/run"
    },
    "steps": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "#/$defs/step"
      }
    }
  },
  "required": [
    "schema_version",
    "run",
    "steps"
  ],
  "$defs": {
    "field": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "state": {
              "const": "not_collected"
            },
            "length": {
              "type": "integer",
              "minimum": 0
            },
            "sha256": {
              "type": "string",
              "pattern": "^[a-f0-9]{64}$"
            },
            "hash_algorithm": {
              "const": "hmac-sha256"
            }
          },
          "required": [
            "state",
            "length",
            "sha256",
            "hash_algorithm"
          ]
        },
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "state": {
              "const": "redacted"
            },
            "length": {
              "type": "integer",
              "minimum": 0
            },
            "sha256": {
              "type": "string",
              "pattern": "^[a-f0-9]{64}$"
            },
            "value": {},
            "hash_algorithm": {
              "const": "hmac-sha256"
            }
          },
          "required": [
            "state",
            "length",
            "sha256",
            "value",
            "hash_algorithm"
          ]
        }
      ]
    },
    "usage": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "input_tokens": {
          "type": "integer",
          "minimum": 0
        },
        "output_tokens": {
          "type": "integer",
          "minimum": 0
        }
      },
      "required": [
        "input_tokens",
        "output_tokens"
      ]
    },
    "tool_call": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "id": {
          "$ref": "#/$defs/field"
        },
        "name": {
          "type": "string"
        },
        "arguments": {
          "$ref": "#/$defs/field"
        }
      },
      "required": [
        "id",
        "name",
        "arguments"
      ]
    },
    "tool_result": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "tool_call_id": {
          "$ref": "#/$defs/field"
        },
        "content": {
          "$ref": "#/$defs/field"
        }
      },
      "required": [
        "tool_call_id",
        "content"
      ]
    },
    "step": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "role": {
          "enum": [
            "system",
            "user",
            "assistant",
            "tool"
          ]
        },
        "content": {
          "$ref": "#/$defs/field"
        },
        "tool_calls": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/tool_call"
          }
        },
        "tool_results": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/tool_result"
          }
        },
        "usage": {
          "oneOf": [
            {
              "$ref": "#/$defs/usage"
            },
            {
              "type": "null"
            }
          ]
        },
        "latency_ms": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0
        }
      },
      "required": [
        "role",
        "content",
        "tool_calls",
        "tool_results",
        "usage",
        "latency_ms"
      ]
    },
    "run": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "format": "uuid"
        },
        "sequence": {
          "type": "integer",
          "minimum": 0
        },
        "model": {
          "type": "string"
        },
        "provider": {
          "enum": [
            "fake",
            "openai_compat",
            "anthropic_compat"
          ]
        },
        "cost": {
          "type": "string",
          "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]+)?([eE][+-]?[0-9]+)?$"
        },
        "cost_status": {
          "enum": [
            "known",
            "unknown"
          ]
        },
        "started_at": {
          "type": "string",
          "format": "date-time"
        },
        "trace_policy": {
          "enum": [
            "minimal",
            "redacted"
          ]
        },
        "redaction_version": {
          "const": "1"
        },
        "status": {
          "enum": [
            "ok",
            "provider_error",
            "budget_exceeded"
          ]
        }
      },
      "required": [
        "id",
        "sequence",
        "model",
        "provider",
        "cost",
        "cost_status",
        "started_at",
        "trace_policy",
        "redaction_version",
        "status"
      ]
    }
  }
}
