{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://actiontrajectories.com/action-trajectories-schema.json",
  "title": "ActionTrajectories Episode",
  "description": "A portable baseline for a temporally aligned action trajectory. Environment-specific extensions are expected.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "release_id",
    "episode",
    "timebase",
    "records",
    "provenance",
    "rights",
    "quality"
  ],
  "properties": {
    "schema_version": {
      "type": "string",
      "const": "1.0.0"
    },
    "release_id": {
      "type": "string",
      "minLength": 1
    },
    "episode": {
      "type": "object",
      "additionalProperties": false,
      "required": ["id", "environment", "task", "started_at_ns", "ended_at_ns", "terminal"],
      "properties": {
        "id": { "type": "string", "minLength": 1 },
        "environment": {
          "type": "object",
          "additionalProperties": false,
          "required": ["name", "version"],
          "properties": {
            "name": { "type": "string" },
            "version": { "type": "string" },
            "configuration": { "type": "object" }
          }
        },
        "task": { "type": "string" },
        "started_at_ns": { "type": "integer", "minimum": 0 },
        "ended_at_ns": { "type": "integer", "minimum": 0 },
        "terminal": {
          "type": "object",
          "required": ["reason", "success"],
          "properties": {
            "reason": { "type": "string" },
            "success": { "type": ["boolean", "null"] }
          }
        }
      }
    },
    "timebase": {
      "type": "object",
      "additionalProperties": false,
      "required": ["clock", "unit", "monotonic", "alignment_notes"],
      "properties": {
        "clock": { "type": "string" },
        "unit": { "const": "nanosecond" },
        "monotonic": { "const": true },
        "alignment_notes": { "type": "string" }
      }
    },
    "records": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": ["timestamp_ns", "observation", "action", "state", "outcome", "valid"],
        "properties": {
          "timestamp_ns": { "type": "integer", "minimum": 0 },
          "observation": {
            "type": "object",
            "required": ["uri", "media_type"],
            "properties": {
              "uri": { "type": "string" },
              "media_type": { "type": "string" },
              "sha256": { "type": ["string", "null"] }
            }
          },
          "action": {
            "type": "object",
            "required": ["raw", "normalized", "observed"],
            "properties": {
              "raw": { "type": "object" },
              "normalized": { "type": "object" },
              "observed": { "type": "boolean" },
              "effective_timestamp_ns": { "type": ["integer", "null"], "minimum": 0 }
            }
          },
          "state": {
            "type": "object",
            "description": "Environment-specific measured state. Unknown values should be null or absent under a declared extension."
          },
          "outcome": {
            "type": "object",
            "properties": {
              "progress": { "type": ["number", "null"] },
              "reward": { "type": ["number", "null"] },
              "events": {
                "type": "array",
                "items": { "type": "string" }
              }
            }
          },
          "valid": {
            "type": "object",
            "required": ["observation", "action", "state"],
            "properties": {
              "observation": { "type": "boolean" },
              "action": { "type": "boolean" },
              "state": { "type": "boolean" }
            }
          }
        }
      }
    },
    "provenance": {
      "type": "object",
      "additionalProperties": false,
      "required": ["collector", "collection_method", "transformations"],
      "properties": {
        "collector": { "type": "string" },
        "collection_method": { "type": "string" },
        "source_release": { "type": ["string", "null"] },
        "transformations": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["name", "version"],
            "properties": {
              "name": { "type": "string" },
              "version": { "type": "string" },
              "parameters": { "type": "object" }
            }
          }
        }
      }
    },
    "rights": {
      "type": "object",
      "additionalProperties": false,
      "required": ["status", "commercial_training", "redistribution", "reviewed_at"],
      "properties": {
        "status": {
          "enum": ["unreviewed", "quarantined", "approved", "restricted", "rejected", "withdrawn"]
        },
        "commercial_training": { "type": ["boolean", "null"] },
        "redistribution": { "type": ["boolean", "null"] },
        "license_or_agreement": { "type": ["string", "null"] },
        "reviewed_at": { "type": "string", "format": "date" },
        "notes": { "type": "string" }
      }
    },
    "quality": {
      "type": "object",
      "additionalProperties": false,
      "required": ["technical_integrity", "temporal_alignment", "semantic_validity", "release_approved"],
      "properties": {
        "technical_integrity": { "$ref": "#/$defs/check" },
        "temporal_alignment": { "$ref": "#/$defs/check" },
        "semantic_validity": { "$ref": "#/$defs/check" },
        "release_approved": { "type": "boolean" }
      }
    }
  },
  "$defs": {
    "check": {
      "type": "object",
      "required": ["status", "method"],
      "properties": {
        "status": { "enum": ["pass", "fail", "unknown"] },
        "method": { "type": "string" },
        "details": { "type": "string" }
      }
    }
  }
}
