{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://trydingday.com/data/agents/v1/schema.json",
  "title": "TrydingDay public agent data v1",
  "description": "Schema for public episode, archive, index, discovery and live snapshot JSON documents.",
  "oneOf": [
    {
      "$ref": "#/$defs/index"
    },
    {
      "$ref": "#/$defs/archiveIndex"
    },
    {
      "$ref": "#/$defs/archiveYear"
    },
    {
      "$ref": "#/$defs/episode"
    },
    {
      "$ref": "#/$defs/discovery"
    },
    {
      "$ref": "#/$defs/liveSnapshot"
    }
  ],
  "$defs": {
    "nullableString": {
      "type": [
        "string",
        "null"
      ]
    },
    "publicValue": {
      "type": [
        "object",
        "array",
        "string",
        "number",
        "boolean",
        "null"
      ]
    },
    "episodeSummary": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "episode_id",
        "symbol",
        "episode_type",
        "published_at",
        "updated_at",
        "tracking_status",
        "stage",
        "episode_url",
        "public_page_url"
      ],
      "properties": {
        "episode_id": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+)*$"
        },
        "symbol": {
          "type": "string"
        },
        "episode_type": {
          "enum": [
            "equity",
            "catch"
          ]
        },
        "published_at": {
          "$ref": "#/$defs/nullableString"
        },
        "updated_at": {
          "$ref": "#/$defs/nullableString"
        },
        "tracking_status": {
          "type": "string"
        },
        "stage": {
          "enum": [
            "tracking",
            "final_closure_pending",
            "closed",
            "in_observation",
            "archived"
          ]
        },
        "episode_url": {
          "type": "string",
          "format": "uri"
        },
        "public_page_url": {
          "type": "string"
        }
      }
    },
    "yearReference": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "year",
        "count",
        "index_url",
        "first_published_at",
        "last_published_at"
      ],
      "properties": {
        "year": {
          "type": "string",
          "pattern": "^(?:[0-9]{4}|unknown)$"
        },
        "count": {
          "type": "integer",
          "minimum": 0
        },
        "index_url": {
          "type": "string",
          "format": "uri"
        },
        "first_published_at": {
          "$ref": "#/$defs/nullableString"
        },
        "last_published_at": {
          "$ref": "#/$defs/nullableString"
        }
      }
    },
    "index": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "schema_version",
        "contract_version",
        "generated_at",
        "active_count",
        "active_episodes",
        "archive_index_url",
        "live_data_url",
        "schema_url"
      ],
      "properties": {
        "schema_version": {
          "const": "tryding-agent-index.v1"
        },
        "contract_version": {
          "const": "tryding-agent-data.v1"
        },
        "generated_at": {
          "type": "string",
          "format": "date-time"
        },
        "active_count": {
          "type": "integer",
          "minimum": 0
        },
        "active_episodes": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/episodeSummary"
          }
        },
        "archive_index_url": {
          "type": "string",
          "format": "uri"
        },
        "live_data_url": {
          "type": "string",
          "format": "uri"
        },
        "schema_url": {
          "type": "string",
          "format": "uri"
        }
      }
    },
    "archiveIndex": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "schema_version",
        "generated_at",
        "years"
      ],
      "properties": {
        "schema_version": {
          "const": "tryding-agent-archive-index.v1"
        },
        "generated_at": {
          "type": "string",
          "format": "date-time"
        },
        "years": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/yearReference"
          }
        }
      }
    },
    "archiveYear": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "schema_version",
        "year",
        "count",
        "episodes"
      ],
      "properties": {
        "schema_version": {
          "const": "tryding-agent-archive-year.v1"
        },
        "year": {
          "type": "string",
          "pattern": "^(?:[0-9]{4}|unknown)$"
        },
        "count": {
          "type": "integer",
          "minimum": 0
        },
        "episodes": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/episodeSummary"
          }
        }
      }
    },
    "liveSnapshot": {
      "type": "object",
      "required": [
        "schema_version",
        "generated_at",
        "publications"
      ],
      "properties": {
        "schema_version": {
          "const": "web-live-snapshot.v8"
        },
        "generated_at": {
          "type": "string",
          "format": "date-time"
        },
        "publications": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/livePublication"
          }
        }
      },
      "additionalProperties": true
    },
    "livePublication": {
      "type": "object",
      "properties": {
        "previous_regular_close": {
          "$ref": "#/$defs/publicValue"
        },
        "return_vs_today_pct": {
          "type": [
            "number",
            "null"
          ],
          "description": "Percentage return from price to previous_regular_close; the daily comparison."
        },
        "return_vs_prior_pct": {
          "type": [
            "number",
            "null"
          ],
          "description": "Compatibility alias of return_vs_today_pct, with the same meaning in every market phase."
        },
        "change_vs_previous_capture_pct_points": {
          "type": [
            "number",
            "null"
          ],
          "description": "Additive percentage-point change in cumulative return versus episode entry since the latest recorded episode capture."
        },
        "change_vs_prior_session_pct": {
          "type": [
            "number",
            "null"
          ],
          "description": "Legacy alias of change_vs_previous_capture_pct_points; it is not the daily return."
        },
        "history": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/liveHistoryRow"
          }
        }
      },
      "additionalProperties": true
    },
    "liveHistoryRow": {
      "type": "object",
      "properties": {
        "return_vs_prior_pct": {
          "type": [
            "number",
            "null"
          ],
          "description": "Percentage return from this row's price to its previous_regular_close, when recorded."
        },
        "change_vs_previous_capture_pct_points": {
          "type": [
            "number",
            "null"
          ],
          "description": "Additive percentage-point change in cumulative return versus episode entry since the preceding recorded capture."
        },
        "change_vs_prior_session_pct": {
          "type": [
            "number",
            "null"
          ],
          "description": "Legacy alias of change_vs_previous_capture_pct_points."
        }
      },
      "additionalProperties": true
    },
    "episode": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "schema_version",
        "episode_id",
        "episode_url",
        "public_page_url",
        "published_at",
        "updated_at",
        "lifecycle",
        "instrument",
        "technical_reference",
        "public_content"
      ],
      "properties": {
        "schema_version": {
          "const": "tryding-agent-episode.v1"
        },
        "episode_id": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+)*$"
        },
        "episode_url": {
          "type": "string",
          "format": "uri"
        },
        "public_page_url": {
          "type": "string"
        },
        "published_at": {
          "$ref": "#/$defs/nullableString",
          "description": "Original publication time as an ISO 8601 UTC timestamp."
        },
        "updated_at": {
          "$ref": "#/$defs/nullableString",
          "description": "Newest recorded publication update or quote time as an ISO 8601 UTC timestamp."
        },
        "lifecycle": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "tracking_status",
            "active_for_tracking",
            "stage"
          ],
          "properties": {
            "tracking_status": {
              "type": "string"
            },
            "active_for_tracking": {
              "type": "boolean"
            },
            "stage": {
              "enum": [
                "tracking",
                "final_closure_pending",
                "closed",
                "in_observation",
                "archived"
              ]
            }
          }
        },
        "instrument": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "type",
            "symbol",
            "exchange",
            "name"
          ],
          "properties": {
            "type": {
              "enum": [
                "equity",
                "catch"
              ]
            },
            "symbol": {
              "type": "string"
            },
            "exchange": {
              "$ref": "#/$defs/nullableString"
            },
            "name": {
              "$ref": "#/$defs/nullableString"
            }
          }
        },
        "technical_reference": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "status"
          ],
          "properties": {
            "status": {
              "type": "string"
            },
            "reason": {
              "$ref": "#/$defs/nullableString"
            },
            "reference_price": {
              "$ref": "#/$defs/publicValue"
            },
            "model_downside_reference": {
              "$ref": "#/$defs/publicValue"
            },
            "model_downside_reference_clamped": {
              "$ref": "#/$defs/publicValue"
            },
            "model_upside_scenario_1": {
              "$ref": "#/$defs/publicValue"
            },
            "model_upside_scenario_2": {
              "$ref": "#/$defs/publicValue"
            },
            "atr_14": {
              "$ref": "#/$defs/publicValue"
            },
            "atr_method": {
              "$ref": "#/$defs/nullableString"
            },
            "method": {
              "$ref": "#/$defs/nullableString"
            },
            "atr_14_source": {
              "$ref": "#/$defs/nullableString"
            },
            "atr_14_source_captured_at": {
              "$ref": "#/$defs/nullableString"
            }
          }
        },
        "public_content": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "date",
            "generated_at",
            "original_published_at",
            "session_tag",
            "label",
            "try_label",
            "public_status",
            "why_today",
            "entry_reasoning",
            "reference_price",
            "scanner",
            "levels",
            "review",
            "updates",
            "observed_outcomes",
            "candidate_comparison_history",
            "candidates",
            "news",
            "transcript_url",
            "initial_transcript_anchor",
            "chart_url",
            "secondary_chart_url",
            "forecast_chart_url",
            "methodology_url",
            "track_record_url",
            "market_timezone"
          ],
          "properties": {
            "date": {
              "$ref": "#/$defs/publicValue"
            },
            "generated_at": {
              "$ref": "#/$defs/publicValue"
            },
            "original_published_at": {
              "$ref": "#/$defs/publicValue"
            },
            "session_tag": {
              "$ref": "#/$defs/publicValue"
            },
            "label": {
              "$ref": "#/$defs/publicValue"
            },
            "try_label": {
              "$ref": "#/$defs/publicValue"
            },
            "public_status": {
              "$ref": "#/$defs/publicValue"
            },
            "why_today": {
              "$ref": "#/$defs/publicValue"
            },
            "entry_reasoning": {
              "$ref": "#/$defs/publicValue"
            },
            "reference_price": {
              "$ref": "#/$defs/publicValue"
            },
            "scanner": {
              "$ref": "#/$defs/publicValue",
              "description": "Scanner data retained from the public episode snapshot. earnings_warning.status=earnings_day means the calendar date is today; it does not specify whether or when results were released."
            },
            "levels": {
              "$ref": "#/$defs/publicValue"
            },
            "review": {
              "$ref": "#/$defs/publicValue"
            },
            "updates": {
              "$ref": "#/$defs/publicValue",
              "description": "Update records retain their own timestamp, price_as_of and vwap_as_of. Match an update to candidate_comparison_history by timestamp; use return_vs_entry_pct with price and reference_price for calculated episode return. The legacy pct value is retained but may reflect a different capture."
            },
            "observed_outcomes": {
              "$ref": "#/$defs/publicValue"
            },
            "candidate_comparison": {
              "$ref": "#/$defs/publicValue",
              "description": "Compatibility property omitted by the current exporter. Use candidate_comparison_history as the canonical comparison series."
            },
            "candidate_comparison_history": {
              "$ref": "#/$defs/publicValue",
              "description": "The single canonical series of comparison captures, ordered oldest to newest. Match each capture to an update by timestamp; the final entry is the latest capture."
            },
            "candidates": {
              "$ref": "#/$defs/publicValue"
            },
            "news": {
              "$ref": "#/$defs/publicValue"
            },
            "transcript_url": {
              "$ref": "#/$defs/publicValue"
            },
            "initial_transcript_anchor": {
              "$ref": "#/$defs/publicValue"
            },
            "chart_url": {
              "$ref": "#/$defs/publicValue"
            },
            "secondary_chart_url": {
              "$ref": "#/$defs/publicValue"
            },
            "forecast_chart_url": {
              "$ref": "#/$defs/publicValue"
            },
            "methodology_url": {
              "$ref": "#/$defs/publicValue"
            },
            "track_record_url": {
              "$ref": "#/$defs/publicValue"
            },
            "market_timezone": {
              "$ref": "#/$defs/publicValue"
            }
          }
        }
      }
    },
    "discovery": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "schema_version",
        "contract_version",
        "index_url",
        "archive_index_url",
        "live_data_url",
        "schema_url"
      ],
      "properties": {
        "schema_version": {
          "const": "tryding-agent-discovery.v1"
        },
        "contract_version": {
          "const": "tryding-agent-data.v1"
        },
        "index_url": {
          "type": "string",
          "format": "uri"
        },
        "archive_index_url": {
          "type": "string",
          "format": "uri"
        },
        "live_data_url": {
          "type": "string",
          "format": "uri"
        },
        "schema_url": {
          "type": "string",
          "format": "uri"
        }
      }
    }
  }
}
