{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://fact.ngo/xray/schemas/record.schema.json",
  "title": "xray record",
  "description": "A single elicited perspective from a language model. One interview cell yields several records; each record is one distinct position.",
  "type": "object",
  "required": [
    "schema_version",
    "created",
    "model",
    "elicitation",
    "stance_type",
    "claim",
    "position_text",
    "confidence",
    "controversy",
    "convergence"
  ],
  "properties": {
    "schema_version": { "const": "1.0" },
    "created": { "type": "string", "format": "date-time" },
    "model": {
      "type": "object",
      "required": ["id", "host"],
      "properties": {
        "id": { "type": "string", "description": "Full provider model id, e.g. @cf/meta/llama-3.1-8b-instruct-fp8" },
        "family": { "type": "string" },
        "version": { "type": "string" },
        "host": { "type": "string", "description": "e.g. cloudflare-workers-ai" },
        "quantization": { "type": "string" },
        "context_window_tokens": { "type": "integer" }
      }
    },
    "elicitation": {
      "type": "object",
      "required": ["session_id", "domain", "lens"],
      "properties": {
        "session_id": { "type": "string" },
        "protocol_version": { "type": "string" },
        "domain": { "type": "string", "description": "Domain id from ontology/domains.yaml, or 'meta' for the self-model cell" },
        "lens": { "type": "string", "description": "Lens id from ontology/lenses.yaml" },
        "turn_refs": { "type": "array", "items": { "type": "integer" }, "description": "Turn numbers in the session transcript that evidence this record" },
        "temperature": { "type": "number" },
        "date": { "type": "string", "format": "date-time" }
      }
    },
    "stance_type": {
      "enum": [
        "assessment",
        "prediction",
        "interpretation",
        "principle",
        "value",
        "methodological",
        "self-description"
      ],
      "description": "assessment=true belief about the world; prediction=expectation about future; interpretation=reading of a past/present phenomenon; principle=general regularity; value=normative commitment; methodological=how to reason in the domain; self-model cell only"
    },
    "claim": { "type": "string", "maxLength": 300, "description": "One-sentence headline of the position, in the elicitor's words" },
    "position_text": { "type": "string", "description": "Verbatim quote from the model expressing the position. Never paraphrased." },
    "paraphrase": { "type": "string", "description": "Faithful fuller restatement by the elicitor, only where the verbatim quote is too tangled to stand alone" },
    "confidence": {
      "type": "object",
      "required": ["assessed"],
      "properties": {
        "model_stated": { "type": ["number", "null"], "description": "Numeric confidence the model itself offered, 0-1, else null" },
        "assessed": { "enum": ["low", "medium", "high"], "description": "Elicitor's assessment of how settled vs speculative the position is" }
      }
    },
    "controversy": { "enum": ["low", "moderate", "high"], "description": "How contested this position is among informed humans" },
    "convergence": {
      "enum": ["pending", "convergent", "divergent", "idiosyncratic"],
      "default": "pending",
      "description": "Cross-model status. Stays 'pending' at elicitation time; set during the later comparison pass: convergent=most models agree; divergent=models split; idiosyncratic=this model alone"
    },
    "conditions": { "type": ["string", "null"], "description": "Circumstances under which the position holds or reverses, as stated by the model" },
    "reasoning_summary": { "type": "string", "description": "The model's stated why, compressed by the elicitor" },
    "flags": {
      "type": "array",
      "items": { "enum": ["refusal", "hedging", "deflection", "boilerplate", "inconsistency", "sycophancy"] },
      "description": "Integrity flags: where the model dodged, hedged, gave boilerplate, contradicted itself, or told the interviewer what it seemed to want to hear"
    },
    "tags": { "type": "array", "items": { "type": "string" } },
    "notes": { "type": "string", "description": "Elicitor notes on context, pressure applied, or anything the structured fields miss" }
  }
}
