{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://raw.githubusercontent.com/DY-2026/GameDesignOS/main/contracts/ul-state.schema.json",
  "$comment": "Copyright (c) 2026 @Paranoia. All rights reserved.",
  "title": "GameDesignOS UL State",
  "description": "Optional Uncertainty Ladder state for controlling uncertainty exposure, failure attribution, progression, transfer, and fallback without changing authority boundaries.",
  "type": "object",
  "required": [
    "schema_version",
    "ul_id",
    "status",
    "target_capability",
    "current_rung",
    "uncertainty_exposure",
    "released_this_round",
    "held_constant",
    "scaffolds_present",
    "consequence_budget",
    "preregistered_signals",
    "attribution_gate",
    "graduation_evidence",
    "transfer_checks",
    "fallback_rung",
    "rollback",
    "stop_rule",
    "human_gate"
  ],
  "additionalProperties": false,
  "properties": {
    "schema_version": { "type": "string", "const": "1.0.0" },
    "ul_id": { "type": "string", "pattern": "^UL-[A-Z0-9-]{3,}$" },
    "status": { "enum": ["candidate", "shadow", "warn", "enforce"] },
    "target_capability": { "type": "string", "minLength": 1 },
    "decision_ref": { "type": ["string", "null"] },
    "voi_gate_ref": { "type": ["string", "null"] },
    "world_model_ref": { "type": ["string", "null"] },
    "current_rung": { "$ref": "#/$defs/rung" },
    "uncertainty_exposure": { "$ref": "#/$defs/uncertainty_exposure" },
    "released_this_round": {
      "type": "array",
      "minItems": 1,
      "maxItems": 2,
      "items": { "$ref": "#/$defs/released_variable" }
    },
    "held_constant": {
      "type": "array",
      "minItems": 1,
      "items": { "type": "string", "minLength": 1 }
    },
    "scaffolds_present": {
      "type": "array",
      "items": { "type": "string", "minLength": 1 }
    },
    "consequence_budget": { "type": "string", "minLength": 1 },
    "preregistered_signals": { "$ref": "#/$defs/preregistered_signals" },
    "attribution_gate": { "$ref": "#/$defs/attribution_gate" },
    "targeted_intervention": { "type": ["string", "null"] },
    "same_rung_replay": { "$ref": "#/$defs/string_array" },
    "graduation_evidence": { "$ref": "#/$defs/string_array" },
    "transfer_checks": { "$ref": "#/$defs/transfer_checks" },
    "next_uncertainty_to_release": { "type": ["string", "null"] },
    "fallback_rung": {
      "anyOf": [
        { "$ref": "#/$defs/rung" },
        { "type": "null" }
      ]
    },
    "rollback": { "type": "string", "minLength": 1 },
    "stop_rule": { "type": "string", "minLength": 1 },
    "human_gate": { "$ref": "#/$defs/human_gate" }
  },
  "$defs": {
    "rung": {
      "enum": ["UL-L0", "UL-L1", "UL-L2", "UL-L3", "UL-L4", "UL-L5"]
    },
    "exposure_level": {
      "enum": ["controlled", "partial", "real"]
    },
    "uncertainty_exposure": {
      "type": "object",
      "required": [
        "input_novelty",
        "context_ambiguity",
        "tool_environment_variability",
        "coordination_variability",
        "authority_and_consequence",
        "evaluation_ambiguity"
      ],
      "additionalProperties": false,
      "properties": {
        "input_novelty": { "$ref": "#/$defs/exposure_level" },
        "context_ambiguity": { "$ref": "#/$defs/exposure_level" },
        "tool_environment_variability": { "$ref": "#/$defs/exposure_level" },
        "coordination_variability": { "$ref": "#/$defs/exposure_level" },
        "authority_and_consequence": {
          "enum": ["sandbox", "reversible", "human_gated_real"]
        },
        "evaluation_ambiguity": { "$ref": "#/$defs/exposure_level" }
      }
    },
    "released_variable": {
      "type": "object",
      "required": ["variable", "reason", "expected_learning"],
      "additionalProperties": false,
      "properties": {
        "variable": { "type": "string", "minLength": 1 },
        "reason": { "type": "string", "minLength": 1 },
        "expected_learning": { "type": "string", "minLength": 1 }
      }
    },
    "string_array": {
      "type": "array",
      "items": { "type": "string", "minLength": 1 }
    },
    "preregistered_signals": {
      "type": "object",
      "required": ["pass", "fail", "confounded", "stop"],
      "additionalProperties": false,
      "properties": {
        "pass": { "$ref": "#/$defs/string_array" },
        "fail": { "$ref": "#/$defs/string_array" },
        "confounded": { "$ref": "#/$defs/string_array" },
        "stop": { "$ref": "#/$defs/string_array" }
      }
    },
    "attribution_gate": {
      "type": "object",
      "required": [
        "observable_failure",
        "candidate_bottlenecks",
        "discriminating_probe",
        "primary_bottleneck",
        "attribution_confidence",
        "evidence_refs"
      ],
      "additionalProperties": false,
      "properties": {
        "observable_failure": { "type": ["string", "null"] },
        "candidate_bottlenecks": { "$ref": "#/$defs/string_array" },
        "discriminating_probe": { "type": ["string", "null"] },
        "primary_bottleneck": { "type": ["string", "null"] },
        "attribution_confidence": {
          "enum": ["not_tested", "low", "medium", "high", "confounded"]
        },
        "evidence_refs": { "$ref": "#/$defs/string_array" }
      }
    },
    "transfer_checks": {
      "type": "object",
      "required": ["near", "medium", "far", "negative_transfer"],
      "additionalProperties": false,
      "properties": {
        "near": { "$ref": "#/$defs/string_array" },
        "medium": { "$ref": "#/$defs/string_array" },
        "far": { "$ref": "#/$defs/string_array" },
        "negative_transfer": { "$ref": "#/$defs/string_array" }
      }
    },
    "human_gate": {
      "type": "object",
      "required": ["required", "reason"],
      "additionalProperties": false,
      "properties": {
        "required": { "type": "boolean" },
        "reason": { "type": "string" }
      }
    }
  }
}
