{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://getzero.dev/contracts/zero.replay_decision_graph.v1.schema.json",
  "title": "ZERO Public Replay Decision Graph v1",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "kind",
    "status",
    "generated_at",
    "canonical_url",
    "public",
    "graph_horizon",
    "coverage",
    "nodes",
    "families",
    "edges",
    "links",
    "privacy_boundary",
    "score_gate",
    "blockers"
  ],
  "properties": {
    "schema_version": { "const": "zero.replay_decision_graph.v1" },
    "kind": { "const": "public_replay_decision_graph" },
    "status": { "enum": ["decision_graph_ready", "decision_graph_degraded"] },
    "generated_at": { "type": "string", "format": "date-time" },
    "canonical_url": { "const": "https://getzero.dev/api/replays/decision-graph" },
    "public": { "const": true },
    "graph_horizon": {
      "type": "object",
      "additionalProperties": false,
      "required": ["scanned_replays", "retained_nodes", "max_nodes"],
      "properties": {
        "scanned_replays": { "type": "integer", "minimum": 0 },
        "retained_nodes": { "type": "integer", "minimum": 0 },
        "max_nodes": { "type": "integer", "minimum": 1 }
      }
    },
    "coverage": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "replay_count",
        "node_count",
        "edge_count",
        "family_count",
        "refusal_family_count",
        "followthrough_family_count",
        "same_policy_family_count",
        "graph_context_count"
      ],
      "properties": {
        "replay_count": { "type": "integer", "minimum": 0 },
        "node_count": { "type": "integer", "minimum": 0 },
        "edge_count": { "type": "integer", "minimum": 0 },
        "family_count": { "type": "integer", "minimum": 0 },
        "refusal_family_count": { "type": "integer", "minimum": 0 },
        "followthrough_family_count": { "type": "integer", "minimum": 0 },
        "same_policy_family_count": { "type": "integer", "minimum": 0 },
        "graph_context_count": { "type": "integer", "minimum": 0 }
      }
    },
    "nodes": {
      "type": "array",
      "items": { "$ref": "#/$defs/node" }
    },
    "families": {
      "type": "array",
      "items": { "$ref": "#/$defs/family" }
    },
    "edges": {
      "type": "array",
      "items": { "$ref": "#/$defs/edge" }
    },
    "links": {
      "type": "object",
      "additionalProperties": false,
      "required": ["replay_index", "entrypoints", "export", "schema"],
      "properties": {
        "replay_index": { "const": "https://getzero.dev/replay" },
        "entrypoints": { "const": "https://getzero.dev/api/replays/entrypoints" },
        "export": { "const": "https://getzero.dev/api/replays/export?limit=40" },
        "schema": { "const": "https://getzero.dev/contracts/zero.replay_decision_graph.v1.schema.json" }
      }
    },
    "privacy_boundary": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "public_only",
        "private_trace_payloads_public",
        "private_keys_public",
        "operator_ids_public",
        "prompt_bodies_public",
        "tool_payloads_public",
        "performance_metrics_public"
      ],
      "properties": {
        "public_only": { "const": true },
        "private_trace_payloads_public": { "const": false },
        "private_keys_public": { "const": false },
        "operator_ids_public": { "const": false },
        "prompt_bodies_public": { "const": false },
        "tool_payloads_public": { "const": false },
        "performance_metrics_public": { "const": false }
      }
    },
    "score_gate": {
      "type": "object",
      "additionalProperties": false,
      "required": ["can_promote_public_score", "reason", "next_blocker"],
      "properties": {
        "can_promote_public_score": { "type": "boolean" },
        "reason": { "type": "string", "minLength": 1 },
        "next_blocker": { "const": "recurring_public_decision_artifacts_missing" }
      }
    },
    "blockers": {
      "type": "array",
      "items": { "type": "string", "minLength": 1 }
    }
  },
  "$defs": {
    "node": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "replay_id",
        "href",
        "graph_context_url",
        "occurred_at",
        "outcome_kind",
        "source_type",
        "operator_handle",
        "agent_handle",
        "summary",
        "journal_status",
        "audit_status",
        "hash_refs"
      ],
      "properties": {
        "replay_id": { "type": "string", "minLength": 1 },
        "href": { "type": "string", "pattern": "^https://getzero\\.dev/replay/.+" },
        "graph_context_url": { "type": "string", "pattern": "^https://getzero\\.dev/api/replays/.+/graph-context$" },
        "occurred_at": { "type": "string", "format": "date-time" },
        "outcome_kind": { "enum": ["closed_trade", "heartbeat", "position", "refusal", "public_evidence"] },
        "source_type": { "type": "string", "minLength": 1 },
        "operator_handle": { "type": "string", "minLength": 1 },
        "agent_handle": { "type": "string", "minLength": 1 },
        "summary": { "type": "string", "minLength": 1 },
        "journal_status": { "enum": ["complete", "partial", "unavailable"] },
        "audit_status": { "enum": ["complete", "partial", "weak"] },
        "hash_refs": {
          "type": "object",
          "additionalProperties": false,
          "required": ["payload_hash", "journal_root_hash"],
          "properties": {
            "payload_hash": { "type": ["string", "null"] },
            "journal_root_hash": { "type": ["string", "null"] }
          }
        }
      }
    },
    "family": {
      "type": "object",
      "additionalProperties": false,
      "required": ["family_id", "family_type", "label", "status", "replay_ids", "graph_context_urls", "sample_count"],
      "properties": {
        "family_id": { "type": "string", "minLength": 1 },
        "family_type": {
          "enum": ["refusal_cluster", "followthrough", "same_policy", "same_journal_root", "same_operator", "same_outcome"]
        },
        "label": { "type": "string", "minLength": 1 },
        "status": { "enum": ["ready", "degraded"] },
        "replay_ids": {
          "type": "array",
          "items": { "type": "string", "minLength": 1 }
        },
        "graph_context_urls": {
          "type": "array",
          "items": { "type": "string", "pattern": "^https://getzero\\.dev/api/replays/.+/graph-context$" }
        },
        "sample_count": { "type": "integer", "minimum": 0 },
        "policy_version": { "type": "string" },
        "policy_hash": { "type": "string", "pattern": "^[a-f0-9]{64}$" }
      }
    },
    "edge": {
      "type": "object",
      "additionalProperties": false,
      "required": ["from", "to", "relation", "href"],
      "properties": {
        "from": { "type": "string", "minLength": 1 },
        "to": { "type": "string", "minLength": 1 },
        "relation": {
          "enum": ["chronological_next", "same_outcome", "same_source", "same_policy", "same_journal_root", "same_operator", "graph_context_link"]
        },
        "href": { "type": "string", "pattern": "^https://getzero\\.dev/(replay|api/replays)/.+" }
      }
    }
  }
}
