{
  "openapi": "3.1.0",
  "info": {
    "title": "Human-AI Chat Interaction Observatory",
    "version": "1.0.0",
    "description": "Analyses the interaction in a human-AI conversation rather than its topic.\n\nLayer 1 is deterministic and returns inside the ingest request. Layer 2\n(LCC and ICCC) is optional, never enabled implicitly, and runs\nasynchronously.\n\nThese measures describe observable and computationally inferred interaction\npatterns. They do not, by themselves, establish learning, mastery, cognitive\neffort, engagement, trust, factual quality, intelligence, personality, or\ncausal influence.\n",
    "license": {
      "name": "MIT"
    }
  },
  "servers": [
    {
      "url": "https://observatory.example.org",
      "description": "Production"
    },
    {
      "url": "http://localhost:8080",
      "description": "Local mock mode"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "health"
    },
    {
      "name": "threads"
    },
    {
      "name": "contributions"
    },
    {
      "name": "analysis"
    },
    {
      "name": "lcc"
    },
    {
      "name": "iccc"
    },
    {
      "name": "owner"
    },
    {
      "name": "research"
    },
    {
      "name": "events"
    }
  ],
  "paths": {
    "/health": {
      "get": {
        "tags": [
          "health"
        ],
        "security": [],
        "summary": "Liveness",
        "responses": {
          "200": {
            "description": "Healthy"
          },
          "503": {
            "description": "Draining"
          }
        }
      }
    },
    "/ready": {
      "get": {
        "tags": [
          "health"
        ],
        "security": [],
        "summary": "Readiness; validates configuration without disclosing secrets",
        "responses": {
          "200": {
            "description": "Ready"
          },
          "503": {
            "description": "Not ready"
          }
        }
      }
    },
    "/api/v1/meta": {
      "get": {
        "tags": [
          "health"
        ],
        "security": [],
        "summary": "Algorithm versions, semantic model version and active drivers",
        "responses": {
          "200": {
            "description": "Metadata"
          }
        }
      }
    },
    "/api/v1/threads": {
      "post": {
        "tags": [
          "threads"
        ],
        "summary": "Create a thread (idempotent on threadId)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateThread"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Already existed"
          },
          "201": {
            "description": "Created"
          },
          "400": {
            "$ref": "#/components/responses/ValidationFailed"
          }
        }
      },
      "get": {
        "tags": [
          "threads"
        ],
        "summary": "List the caller's threads",
        "responses": {
          "200": {
            "description": "Threads"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "get": {
        "tags": [
          "threads"
        ],
        "summary": "Read a thread and the caller's effective access",
        "responses": {
          "200": {
            "description": "Thread"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "delete": {
        "tags": [
          "threads"
        ],
        "summary": "Delete, or record a deletion request when retention forbids deletion",
        "responses": {
          "202": {
            "description": "Deletion requested and recorded"
          },
          "204": {
            "description": "Deleted"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/participants": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "post": {
        "tags": [
          "threads"
        ],
        "summary": "Register a participant",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Participant"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created"
          }
        }
      },
      "get": {
        "tags": [
          "threads"
        ],
        "summary": "List participants (pseudonymous for researchers)",
        "responses": {
          "200": {
            "description": "Participants"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/turns": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "post": {
        "tags": [
          "contributions"
        ],
        "summary": "Ingest one contribution and return Layer 1 immediately",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTurn"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Idempotent replay"
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IngestResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationFailed"
          },
          "409": {
            "description": "Thread is pending deletion"
          }
        }
      },
      "get": {
        "tags": [
          "contributions"
        ],
        "summary": "List contributions, filtered by grant scope",
        "responses": {
          "200": {
            "description": "Contributions"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/turns/batch": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "post": {
        "tags": [
          "contributions"
        ],
        "summary": "Ingest up to 500 contributions in order",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "turns"
                ],
                "properties": {
                  "turns": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 500,
                    "items": {
                      "$ref": "#/components/schemas/CreateTurn"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Ingested"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/turns/{turnId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        },
        {
          "$ref": "#/components/parameters/turnId"
        }
      ],
      "get": {
        "tags": [
          "contributions"
        ],
        "summary": "One contribution with its core analysis",
        "responses": {
          "200": {
            "description": "Contribution"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/analysis": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "get": {
        "tags": [
          "analysis"
        ],
        "summary": "Thread-level Layer 1 analysis with its versioned envelope",
        "responses": {
          "200": {
            "description": "Analysis"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/analysis/turns/{turnId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        },
        {
          "$ref": "#/components/parameters/turnId"
        }
      ],
      "get": {
        "tags": [
          "analysis"
        ],
        "summary": "Per-turn measures, plus speech acts under the speech_acts scope",
        "responses": {
          "200": {
            "description": "Analysis"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/reanalyze": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "post": {
        "tags": [
          "analysis"
        ],
        "summary": "Recompute Layer 1 and re-enqueue Layer 2; safe to repeat",
        "responses": {
          "202": {
            "description": "Reanalysis started"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/semantic-extension": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "get": {
        "tags": [
          "analysis"
        ],
        "summary": "Semantic configuration and per-engine applicability with reasons",
        "responses": {
          "200": {
            "description": "Configuration"
          }
        }
      },
      "put": {
        "tags": [
          "analysis"
        ],
        "summary": "Set the semantic configuration; requesting an engine requires its block",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SemanticConfiguration"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated"
          },
          "400": {
            "$ref": "#/components/responses/ValidationFailed"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/semantic-analysis": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "get": {
        "tags": [
          "analysis"
        ],
        "summary": "Shared semantic artifacts; units and embeddings are separately scoped",
        "responses": {
          "200": {
            "description": "Artifacts"
          }
        }
      }
    },
    "/api/v1/lcc/reference-models": {
      "post": {
        "tags": [
          "lcc"
        ],
        "summary": "Publish a reference model version",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReferenceModel"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Published"
          },
          "409": {
            "description": "Version already exists"
          }
        }
      },
      "get": {
        "tags": [
          "lcc"
        ],
        "summary": "List reference models",
        "responses": {
          "200": {
            "description": "Reference models"
          }
        }
      }
    },
    "/api/v1/lcc/reference-models/{referenceModelId}": {
      "parameters": [
        {
          "name": "referenceModelId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "version",
          "in": "query",
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "lcc"
        ],
        "summary": "Read a reference model, optionally at a specific version",
        "responses": {
          "200": {
            "description": "Reference model"
          }
        }
      },
      "put": {
        "tags": [
          "lcc"
        ],
        "summary": "Publish a new version (versions are immutable)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReferenceModel"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Published"
          },
          "409": {
            "description": "A new version string is required"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/lcc": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "get": {
        "tags": [
          "lcc"
        ],
        "summary": "LCC curves, or not_applicable with reasons",
        "responses": {
          "200": {
            "description": "Curves or a not_applicable result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LccResult"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/lcc/learners/{learnerId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        },
        {
          "name": "learnerId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "lcc"
        ],
        "summary": "One learner's series",
        "responses": {
          "200": {
            "description": "Series"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/lcc/turns/{turnId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        },
        {
          "$ref": "#/components/parameters/turnId"
        }
      ],
      "get": {
        "tags": [
          "lcc"
        ],
        "summary": "One LCC curve point",
        "responses": {
          "200": {
            "description": "Point"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/lcc/recalculate": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "post": {
        "tags": [
          "lcc"
        ],
        "summary": "Queue an LCC recalculation",
        "responses": {
          "202": {
            "description": "Queued"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/iccc": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "get": {
        "tags": [
          "iccc"
        ],
        "summary": "Six curves per participant, or not_applicable with reasons",
        "responses": {
          "200": {
            "description": "Curves",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IcccResult"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/iccc/participants": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "get": {
        "tags": [
          "iccc"
        ],
        "summary": "Participant summaries",
        "responses": {
          "200": {
            "description": "Participants"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/iccc/participants/{participantId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        },
        {
          "name": "participantId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "iccc"
        ],
        "summary": "One participant's series",
        "responses": {
          "200": {
            "description": "Series"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/iccc/contributions/{contributionId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        },
        {
          "name": "contributionId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "iccc"
        ],
        "summary": "One ICCC curve point",
        "responses": {
          "200": {
            "description": "Point"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/iccc/configuration": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "get": {
        "tags": [
          "iccc"
        ],
        "summary": "Read the ICCC configuration",
        "responses": {
          "200": {
            "description": "Configuration"
          }
        }
      },
      "put": {
        "tags": [
          "iccc"
        ],
        "summary": "Set the ICCC configuration and queue a recalculation",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IcccConfiguration"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated; includes a comparabilityWarning when existing curves become incomparable"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/iccc/recalculate": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "post": {
        "tags": [
          "iccc"
        ],
        "summary": "Queue an ICCC recalculation",
        "responses": {
          "202": {
            "description": "Queued"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/iccc/comparability": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        },
        {
          "name": "a",
          "in": "query",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "b",
          "in": "query",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "iccc"
        ],
        "summary": "Whether two participants' curves may be compared",
        "responses": {
          "200": {
            "description": "Comparability verdict"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/events": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "get": {
        "tags": [
          "events"
        ],
        "summary": "Server-Sent Events for this thread",
        "description": "Supports Last-Event-ID replay, reconnects and heartbeats. Authorization\nruns before the stream opens. Internal owner keys are stripped from\nevery frame.\n",
        "responses": {
          "200": {
            "description": "Event stream",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/me/threads": {
      "get": {
        "tags": [
          "owner"
        ],
        "summary": "The owner's threads",
        "responses": {
          "200": {
            "description": "Threads"
          }
        }
      }
    },
    "/api/v1/me/threads/{threadId}/archive": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "get": {
        "tags": [
          "owner"
        ],
        "summary": "Complete owner archive including access history",
        "responses": {
          "200": {
            "description": "Archive"
          }
        }
      }
    },
    "/api/v1/me/threads/{threadId}/exports": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "post": {
        "tags": [
          "owner"
        ],
        "summary": "Start an asynchronous export",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "format": {
                    "type": "string",
                    "enum": [
                      "json",
                      "jsonl",
                      "csv"
                    ],
                    "default": "json"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Export queued"
          }
        }
      }
    },
    "/api/v1/me/threads/{threadId}/exports/inline": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        },
        {
          "name": "format",
          "in": "query",
          "schema": {
            "type": "string",
            "enum": [
              "json",
              "jsonl",
              "csv"
            ]
          }
        }
      ],
      "get": {
        "tags": [
          "owner"
        ],
        "summary": "Synchronous export",
        "responses": {
          "200": {
            "description": "Export body"
          }
        }
      }
    },
    "/api/v1/me/exports/{exportId}": {
      "parameters": [
        {
          "name": "exportId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "owner"
        ],
        "summary": "Export status and, once complete, a short-lived signed URL",
        "responses": {
          "200": {
            "description": "Export record"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/grants": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "post": {
        "tags": [
          "research"
        ],
        "summary": "Grant scoped research access (owner only)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateGrant"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Granted"
          }
        }
      },
      "get": {
        "tags": [
          "research"
        ],
        "summary": "List grants (owner only)",
        "responses": {
          "200": {
            "description": "Grants"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/grants/{grantId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        },
        {
          "name": "grantId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "delete": {
        "tags": [
          "research"
        ],
        "summary": "Revoke immediately",
        "responses": {
          "200": {
            "description": "Revoked"
          }
        }
      }
    },
    "/api/v1/threads/{threadId}/access-history": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "get": {
        "tags": [
          "research"
        ],
        "summary": "Audited access (owner only)",
        "responses": {
          "200": {
            "description": "Events"
          }
        }
      }
    },
    "/api/v1/research/threads/{threadId}/analysis": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "get": {
        "tags": [
          "research"
        ],
        "summary": "Grant-filtered thread analysis",
        "responses": {
          "200": {
            "description": "Filtered analysis"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/research/threads/{threadId}/lcc": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "get": {
        "tags": [
          "research"
        ],
        "summary": "LCC points; requires lcc_curves. Reference-model content is never disclosed.",
        "responses": {
          "200": {
            "description": "Points"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/research/threads/{threadId}/iccc": {
      "parameters": [
        {
          "$ref": "#/components/parameters/threadId"
        }
      ],
      "get": {
        "tags": [
          "research"
        ],
        "summary": "ICCC series; requires iccc_curves",
        "responses": {
          "200": {
            "description": "Series"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/research/exports": {
      "post": {
        "tags": [
          "research"
        ],
        "summary": "Export the permitted fields; requires the export scope per thread",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "threadIds"
                ],
                "properties": {
                  "format": {
                    "type": "string",
                    "enum": [
                      "json",
                      "jsonl",
                      "csv"
                    ]
                  },
                  "threadIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Export body"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    },
    "parameters": {
      "threadId": {
        "name": "threadId",
        "in": "path",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/Identifier"
        }
      },
      "turnId": {
        "name": "turnId",
        "in": "path",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/Identifier"
        }
      }
    },
    "responses": {
      "ValidationFailed": {
        "description": "Request validation failed",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Denied, or a required scope was not granted",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "Not found or not visible to this principal",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Identifier": {
        "type": "string",
        "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$",
        "description": "Opaque identifier. Never an email address or a JWT subject."
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "requestId": {
                "type": "string"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              }
            }
          }
        }
      },
      "InteractionType": {
        "type": "string",
        "enum": [
          "general_dyad",
          "tutorial_dyad",
          "multi_person_discussion",
          "multi_agent_discussion",
          "group_tutoring"
        ]
      },
      "QualityFlag": {
        "type": "object",
        "required": [
          "code",
          "severity",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string"
          },
          "severity": {
            "type": "string",
            "enum": [
              "info",
              "warning",
              "error"
            ]
          },
          "message": {
            "type": "string"
          },
          "field": {
            "type": "string"
          }
        }
      },
      "TokenCount": {
        "type": "object",
        "properties": {
          "value": {
            "type": [
              "integer",
              "null"
            ]
          },
          "source": {
            "type": "string",
            "enum": [
              "provider_reported",
              "locally_counted",
              "estimated"
            ]
          }
        }
      },
      "Participant": {
        "type": "object",
        "required": [
          "participantId",
          "type",
          "roles"
        ],
        "properties": {
          "participantId": {
            "$ref": "#/components/schemas/Identifier"
          },
          "type": {
            "type": "string",
            "enum": [
              "human",
              "assistant",
              "agent",
              "avatar",
              "system",
              "tool"
            ]
          },
          "roles": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "enum": [
                "learner",
                "tutor",
                "moderator",
                "peer",
                "assistant",
                "other"
              ]
            }
          },
          "displayLabel": {
            "type": "string"
          },
          "model": {
            "type": "string"
          },
          "provider": {
            "type": "string"
          },
          "consentVersion": {
            "type": "string"
          }
        }
      },
      "LccConfiguration": {
        "type": "object",
        "required": [
          "referenceModelId",
          "learnerParticipantIds",
          "tutorParticipantIds"
        ],
        "properties": {
          "referenceModelId": {
            "$ref": "#/components/schemas/Identifier"
          },
          "referenceModelVersion": {
            "type": "string"
          },
          "learnerParticipantIds": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/Identifier"
            }
          },
          "tutorParticipantIds": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/Identifier"
            }
          },
          "classificationMethod": {
            "type": "string",
            "enum": [
              "factor_product",
              "direct_semantic_classification",
              "hybrid"
            ],
            "default": "hybrid"
          }
        }
      },
      "IcccConfiguration": {
        "type": "object",
        "properties": {
          "calculationMode": {
            "type": "string",
            "enum": [
              "cumulative",
              "rolling_window",
              "exponential_decay"
            ]
          },
          "rollingWindowContributions": {
            "type": "integer",
            "minimum": 1
          },
          "rollingWindowMinutes": {
            "type": "number"
          },
          "decayLambda": {
            "type": "number"
          },
          "distanceUnit": {
            "type": "string",
            "enum": [
              "contributions",
              "seconds",
              "minutes"
            ]
          },
          "smoothing": {
            "type": "string",
            "enum": [
              "none",
              "moving_average",
              "ewma"
            ]
          },
          "smoothingParameter": {
            "type": "number"
          },
          "normalization": {
            "type": "string",
            "enum": [
              "none",
              "theoretically_anchored",
              "within_thread_minmax",
              "within_participant_zscore",
              "cohort_reference_zscore"
            ]
          }
        }
      },
      "SemanticConfiguration": {
        "type": "object",
        "required": [
          "interactionType"
        ],
        "description": "Layer 2 is never enabled implicitly. Requesting an engine requires its\nconfiguration block, and mode \"none\" cannot be combined with enabled.\n",
        "properties": {
          "enabled": {
            "type": "boolean",
            "default": false
          },
          "mode": {
            "type": "string",
            "enum": [
              "none",
              "lcc",
              "iccc",
              "lcc_and_iccc"
            ],
            "default": "none"
          },
          "interactionType": {
            "$ref": "#/components/schemas/InteractionType"
          },
          "lcc": {
            "$ref": "#/components/schemas/LccConfiguration"
          },
          "iccc": {
            "$ref": "#/components/schemas/IcccConfiguration"
          }
        }
      },
      "CreateThread": {
        "type": "object",
        "required": [
          "interactionType"
        ],
        "properties": {
          "threadId": {
            "$ref": "#/components/schemas/Identifier"
          },
          "title": {
            "type": "string",
            "maxLength": 300
          },
          "interactionType": {
            "$ref": "#/components/schemas/InteractionType"
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "consentVersion": {
            "type": "string"
          },
          "sourceApplicationId": {
            "$ref": "#/components/schemas/Identifier"
          },
          "semanticConfiguration": {
            "$ref": "#/components/schemas/SemanticConfiguration"
          },
          "participants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Participant"
            }
          },
          "metadata": {
            "type": "object"
          }
        }
      },
      "Usage": {
        "type": "object",
        "description": "Provider-reported usage. A missing figure is never replaced by a local estimate.",
        "properties": {
          "newInputTokens": {
            "type": "integer",
            "minimum": 0
          },
          "totalApiInputTokens": {
            "type": "integer",
            "minimum": 0
          },
          "outputTokens": {
            "type": "integer",
            "minimum": 0
          },
          "visibleOutputTokens": {
            "type": "integer",
            "minimum": 0
          },
          "cachedInputTokens": {
            "type": "integer",
            "minimum": 0
          },
          "reasoningTokens": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "CreateTurn": {
        "type": "object",
        "required": [
          "participantId",
          "speakerType"
        ],
        "properties": {
          "turnId": {
            "$ref": "#/components/schemas/Identifier"
          },
          "parentTurnId": {
            "$ref": "#/components/schemas/Identifier"
          },
          "sequence": {
            "type": "integer",
            "minimum": 0
          },
          "participantId": {
            "$ref": "#/components/schemas/Identifier"
          },
          "speakerType": {
            "type": "string",
            "enum": [
              "human",
              "assistant",
              "agent",
              "avatar",
              "system",
              "tool"
            ]
          },
          "text": {
            "type": "string",
            "maxLength": 200000
          },
          "explicitTargetParticipantIds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Identifier"
            }
          },
          "submittedAt": {
            "type": "string",
            "format": "date-time"
          },
          "firstTokenAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastTokenAt": {
            "type": "string",
            "format": "date-time"
          },
          "model": {
            "type": "string"
          },
          "provider": {
            "type": "string"
          },
          "finishReason": {
            "type": "string"
          },
          "usage": {
            "$ref": "#/components/schemas/Usage"
          },
          "metadata": {
            "type": "object"
          }
        }
      },
      "IngestResult": {
        "type": "object",
        "properties": {
          "created": {
            "type": "boolean"
          },
          "contribution": {
            "type": "object"
          },
          "analysis": {
            "type": "object",
            "properties": {
              "layer1": {
                "type": "object"
              },
              "layer1Status": {
                "type": "string",
                "enum": [
                  "completed"
                ]
              },
              "layer2Status": {
                "type": "string",
                "enum": [
                  "queued",
                  "not_applicable"
                ]
              },
              "speechActStatus": {
                "type": "string"
              }
            }
          },
          "jobIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "ReferenceModel": {
        "type": "object",
        "required": [
          "questionOrProblem",
          "expectations"
        ],
        "properties": {
          "referenceModelId": {
            "$ref": "#/components/schemas/Identifier"
          },
          "version": {
            "type": "string",
            "default": "1.0.0"
          },
          "learningObjective": {
            "type": "string"
          },
          "questionOrProblem": {
            "type": "string",
            "minLength": 1
          },
          "language": {
            "type": "string",
            "default": "en"
          },
          "expectations": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "required": [
                "expectationId",
                "description"
              ],
              "properties": {
                "expectationId": {
                  "$ref": "#/components/schemas/Identifier"
                },
                "description": {
                  "type": "string"
                },
                "weight": {
                  "type": "number",
                  "default": 1
                },
                "required": {
                  "type": "boolean"
                }
              }
            }
          },
          "misconceptions": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "misconceptionId",
                "description"
              ],
              "properties": {
                "misconceptionId": {
                  "$ref": "#/components/schemas/Identifier"
                },
                "description": {
                  "type": "string"
                },
                "weight": {
                  "type": "number",
                  "default": 1
                }
              }
            }
          }
        }
      },
      "LccCurvePoint": {
        "type": "object",
        "description": "RN + RO + IN + IO = 1. Null values carry a quality flag.",
        "properties": {
          "turnId": {
            "type": "string"
          },
          "learnerId": {
            "type": "string"
          },
          "sequence": {
            "type": "integer"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "relevance": {
            "type": [
              "number",
              "null"
            ]
          },
          "novelty": {
            "type": [
              "number",
              "null"
            ]
          },
          "rn": {
            "type": [
              "number",
              "null"
            ]
          },
          "ro": {
            "type": [
              "number",
              "null"
            ]
          },
          "in": {
            "type": [
              "number",
              "null"
            ]
          },
          "io": {
            "type": [
              "number",
              "null"
            ]
          },
          "unmappedIrrelevantNew": {
            "type": [
              "number",
              "null"
            ]
          },
          "unmappedIrrelevantOld": {
            "type": [
              "number",
              "null"
            ]
          },
          "overallScore": {
            "type": [
              "number",
              "null"
            ]
          },
          "instructionalState": {
            "type": "string"
          },
          "candidateTutoringMoves": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "referenceModelId": {
            "type": "string"
          },
          "referenceModelVersion": {
            "type": "string"
          },
          "semanticModelVersion": {
            "type": "string"
          },
          "algorithmVersion": {
            "type": "string"
          },
          "qualityFlags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "LccResult": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "completed",
              "pending",
              "not_applicable"
            ]
          },
          "reason": {
            "type": "string"
          },
          "learners": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "learnerId": {
                  "type": "string"
                },
                "points": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LccCurvePoint"
                  }
                }
              }
            }
          },
          "curves": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "prohibitedInterpretation": {
            "type": "string"
          }
        }
      },
      "IcccMetricValue": {
        "type": "object",
        "properties": {
          "rawValue": {
            "type": [
              "number",
              "null"
            ]
          },
          "normalizedValue": {
            "type": [
              "number",
              "null"
            ]
          },
          "confidence": {
            "type": "number"
          },
          "sampleSize": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "enum": [
              "available",
              "provisional",
              "insufficient_history",
              "not_applicable",
              "failed"
            ]
          },
          "evidenceContributionIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "qualityFlags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QualityFlag"
            }
          },
          "detail": {
            "type": "object"
          }
        }
      },
      "IcccCurvePoint": {
        "type": "object",
        "properties": {
          "participantId": {
            "type": "string"
          },
          "contributionId": {
            "type": "string"
          },
          "sequence": {
            "type": "integer"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "values": {
            "type": "object",
            "properties": {
              "participation": {
                "$ref": "#/components/schemas/IcccMetricValue"
              },
              "overallResponsivity": {
                "$ref": "#/components/schemas/IcccMetricValue"
              },
              "internalCohesion": {
                "$ref": "#/components/schemas/IcccMetricValue"
              },
              "socialImpact": {
                "$ref": "#/components/schemas/IcccMetricValue"
              },
              "newness": {
                "$ref": "#/components/schemas/IcccMetricValue"
              },
              "communicationDensity": {
                "$ref": "#/components/schemas/IcccMetricValue"
              }
            }
          },
          "provisional": {
            "type": "boolean"
          },
          "socialImpactState": {
            "type": "string",
            "enum": [
              "provisional",
              "stabilizing",
              "final"
            ]
          },
          "revision": {
            "type": "integer"
          },
          "calculationMode": {
            "type": "string"
          },
          "algorithmVersion": {
            "type": "string"
          },
          "semanticModelVersion": {
            "type": "string"
          }
        }
      },
      "IcccResult": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "completed",
              "pending",
              "not_applicable"
            ]
          },
          "reason": {
            "type": "string"
          },
          "participants": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "participantId": {
                  "type": "string"
                },
                "points": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/IcccCurvePoint"
                  }
                },
                "smoothed": {
                  "type": "object"
                }
              }
            }
          },
          "metrics": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "provisionalPointCount": {
            "type": "integer"
          },
          "prohibitedInterpretation": {
            "type": "string"
          }
        }
      },
      "ResearchScope": {
        "type": "string",
        "enum": [
          "aggregate_metrics",
          "turn_metrics",
          "speech_acts",
          "timestamps",
          "token_usage",
          "pseudonymized_text",
          "raw_text",
          "lcc_curves",
          "lcc_expectation_matches",
          "lcc_misconception_matches",
          "iccc_curves",
          "iccc_contribution_scores",
          "semantic_units",
          "semantic_representations",
          "export"
        ]
      },
      "CreateGrant": {
        "type": "object",
        "required": [
          "researcherId",
          "scopes",
          "consentVersion",
          "purpose"
        ],
        "properties": {
          "researcherId": {
            "type": "string"
          },
          "projectId": {
            "$ref": "#/components/schemas/Identifier"
          },
          "threadIds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Identifier"
            }
          },
          "scopes": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/ResearchScope"
            }
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "consentVersion": {
            "type": "string"
          },
          "purpose": {
            "type": "string"
          }
        }
      }
    }
  }
}
