{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://traittune.com/.well-known/psydna-schema.json",
  "title": "PsyDNA Profile Export",
  "description": "Portable, signed personality profile from TraitTune. v0.1 schema — subject to refinement before GA; agents should accept additional unknown fields gracefully.",
  "version": "0.1",
  "type": "object",
  "required": ["version", "subject_id", "issued_at", "expires_at", "dimensions", "signature"],
  "additionalProperties": false,
  "properties": {
    "version": {
      "type": "string",
      "const": "0.1",
      "description": "Schema version. Will be bumped before any breaking change."
    },
    "subject_id": {
      "type": "string",
      "description": "Opaque, non-PII identifier — the subject's TraitTune-internal UUID, salted per-export so it cannot be cross-referenced across exports.",
      "minLength": 32,
      "maxLength": 64
    },
    "issued_at": {
      "type": "string",
      "format": "date-time",
      "description": "RFC 3339 timestamp of export generation."
    },
    "expires_at": {
      "type": "string",
      "format": "date-time",
      "description": "RFC 3339 timestamp after which the export must be rejected. Typically 24h after issue."
    },
    "dimensions": {
      "type": "array",
      "minItems": 15,
      "maxItems": 15,
      "description": "All 15 PsyDNA dimensions. Order is canonical and stable across exports.",
      "items": {
        "type": "object",
        "required": ["name", "theta", "se"],
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable bipolar dimension name, e.g. 'Expressive ↔ Reserved'."
          },
          "theta": {
            "type": "number",
            "minimum": -4,
            "maximum": 4,
            "description": "IRT trait location estimate on the 5-point bipolar scale, expressed as a z-score (≈ N(0,1) in the calibration population)."
          },
          "se": {
            "type": "number",
            "minimum": 0,
            "description": "Standard error of the theta estimate. SE ≤ 0.30 is typically considered a 'confident' read; agents should soften claims when SE > 0.50."
          },
          "calibration_run_id": {
            "type": "string",
            "description": "Optional pointer to the immutable irt_calibration_runs row that produced the item parameters used for this estimate."
          }
        }
      }
    },
    "signature": {
      "type": "object",
      "required": ["algorithm", "value", "key_id"],
      "additionalProperties": false,
      "description": "Ed25519 signature over the canonical JSON form of the object (RFC 8785 JSON Canonicalization Scheme), with `signature` itself excluded.",
      "properties": {
        "algorithm": {
          "type": "string",
          "const": "Ed25519"
        },
        "value": {
          "type": "string",
          "description": "Base64url-encoded signature bytes."
        },
        "key_id": {
          "type": "string",
          "description": "Identifier of the TraitTune signing key. Public keys served at /.well-known/psydna-signing-keys.json (TBD)."
        }
      }
    }
  }
}
