{
  "openapi": "3.1.1",
  "info": {
    "title": "Kuberdata API",
    "version": "0.3.0-draft",
    "description": "Contrato público proposto. API em preparação, sem endpoint operacional. Exemplos sintéticos. Tenant derivado da credencial; dados privados segregados; créditos com orçamento prévio."
  },
  "servers": [
    {
      "url": "https://api.example.invalid/v1"
    }
  ],
  "security": [
    {
      "ApiKey": []
    }
  ],
  "paths": {
    "/questions": {
      "get": {
        "operationId": "listQuestions",
        "summary": "Listar questões autorizadas em um snapshot estável",
        "x-required-scope": "questions:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/ReadIdempotency"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "name": "board_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "position_id",
            "in": "query",
            "description": "Obrigatório quando quality=certified; servidor retorna 422 se faltar escopo",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "quality",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "available",
                "certified"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Objetos entregues são medidos; certified nunca inclui candidatos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuestionPage"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/questions/{id}": {
      "get": {
        "operationId": "getQuestion",
        "x-required-scope": "questions:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/ReadIdempotency"
          },
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "name": "revision",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "If-None-Match",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Item com origem, licença e estados de qualidade",
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              },
              "X-Usage-Receipt-Id": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Question"
                }
              }
            }
          },
          "304": {
            "description": "Sem alteração e sem nova cobrança de objeto"
          },
          "410": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/search": {
      "post": {
        "operationId": "search",
        "x-required-scope": "search:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Idempotency"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "query",
                  "mode",
                  "quality",
                  "price_version",
                  "max_credits"
                ],
                "allOf": [
                  {
                    "if": {
                      "properties": {
                        "quality": {
                          "const": "certified"
                        }
                      }
                    },
                    "then": {
                      "required": [
                        "position_id"
                      ]
                    }
                  }
                ],
                "properties": {
                  "query": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 4000
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "lexical",
                      "semantic"
                    ],
                    "description": "Seleciona S01 ou S02 antes da cobrança"
                  },
                  "position_id": {
                    "type": "string"
                  },
                  "quality": {
                    "type": "string",
                    "enum": [
                      "available",
                      "certified"
                    ]
                  },
                  "limit": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 20,
                    "default": 10
                  },
                  "price_version": {
                    "type": "string"
                  },
                  "max_amount_brl": {
                    "type": "number",
                    "minimum": 0,
                    "deprecated": true
                  },
                  "max_credits": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Créditos de serviço; 1 crédito = R$0,01 nesta versão."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "IDs e scores de relevância; score não representa certificação",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "snapshot_id",
                    "matches",
                    "abstained",
                    "usage_receipt_id"
                  ],
                  "properties": {
                    "snapshot_id": {
                      "type": "string"
                    },
                    "matches": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "revision",
                          "score"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "revision": {
                            "type": "integer",
                            "minimum": 1
                          },
                          "score": {
                            "type": "number",
                            "description": "Score específico do retrieval; não probabilidade"
                          }
                        }
                      }
                    },
                    "abstained": {
                      "type": "boolean"
                    },
                    "abstention_reason": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "usage_receipt_id": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/exams/{id}": {
      "get": {
        "operationId": "getExam",
        "x-required-scope": "exams:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "Concurso e estado documental; campos não documentados permanecem nulos",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "revision",
                    "title",
                    "evidence_stage",
                    "position_ids",
                    "document_version_ids"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "revision": {
                      "type": "integer",
                      "minimum": 1
                    },
                    "title": {
                      "type": "string"
                    },
                    "program_id": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "evidence_stage": {
                      "type": "string",
                      "enum": [
                        "regulated",
                        "allocation_documented",
                        "authorization_documented",
                        "organizer_contracted",
                        "notice_published",
                        "registration_open",
                        "suspended",
                        "cancelled",
                        "completed"
                      ]
                    },
                    "position_ids": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "document_version_ids": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "exam_date": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/positions/{id}/syllabus": {
      "get": {
        "operationId": "getSyllabus",
        "x-required-scope": "syllabi:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "name": "layer",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "documentary",
                "pedagogical"
              ]
            }
          },
          {
            "name": "as_of",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pacote versionado; vazio não é preenchido por inferência de atribuições",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "position_id",
                    "revision",
                    "layer",
                    "nodes"
                  ],
                  "properties": {
                    "position_id": {
                      "type": "string"
                    },
                    "revision": {
                      "type": "integer",
                      "minimum": 1
                    },
                    "layer": {
                      "type": "string",
                      "enum": [
                        "documentary",
                        "pedagogical"
                      ]
                    },
                    "nodes": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Node"
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/quotes": {
      "post": {
        "operationId": "createQuote",
        "summary": "Orçar tarefa antes de reservar saldo; sem cobrança",
        "x-required-scope": "jobs:write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "sku",
                  "input"
                ],
                "properties": {
                  "sku": {
                    "type": "string",
                    "enum": [
                      "D02",
                      "D03",
                      "D04",
                      "A01",
                      "Q06"
                    ]
                  },
                  "input": {
                    "description": "Input completo; servidor verifica dimensões, autorização, política e compatibilidade com SKU antes de calcular digest",
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/DocumentJobInput"
                      },
                      {
                        "$ref": "#/components/schemas/RecurrenceInput"
                      },
                      {
                        "$ref": "#/components/schemas/ClassificationInput"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Cotação vinculada a tenant, input, SKU e política; validade curta",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "expires_at",
                    "max_amount_brl",
                    "price_version",
                    "input_digest",
                    "max_credits",
                    "components"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "max_amount_brl": {
                      "type": "number",
                      "minimum": 0
                    },
                    "price_version": {
                      "type": "string"
                    },
                    "input_digest": {
                      "type": "string",
                      "pattern": "^[a-f0-9]{64}$"
                    },
                    "max_credits": {
                      "type": "number",
                      "minimum": 0,
                      "description": "Créditos de serviço; 1 crédito = R$0,01 nesta versão."
                    },
                    "components": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "sku",
                          "quantity",
                          "credits"
                        ],
                        "properties": {
                          "sku": {
                            "type": "string"
                          },
                          "quantity": {
                            "type": "number",
                            "minimum": 0
                          },
                          "credits": {
                            "type": "number",
                            "minimum": 0
                          }
                        }
                      },
                      "description": "Decomposição do orçamento, incluindo extração/programa quando necessários; sem dupla cobrança."
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/document-jobs": {
      "post": {
        "operationId": "createDocumentJob",
        "x-required-scope": "documents:write",
        "parameters": [
          {
            "$ref": "#/components/parameters/Idempotency"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "input",
                  "quote_id",
                  "max_credits"
                ],
                "properties": {
                  "input": {
                    "$ref": "#/components/schemas/DocumentJobInput"
                  },
                  "quote_id": {
                    "type": "string"
                  },
                  "max_amount_brl": {
                    "type": "number",
                    "minimum": 0,
                    "deprecated": true
                  },
                  "max_credits": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Créditos de serviço; 1 crédito = R$0,01 nesta versão."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Job aceito com reserva de saldo; não equivale a certificado",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/jobs/{id}": {
      "get": {
        "operationId": "getJob",
        "x-required-scope": "jobs:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "Estado sem custo; resultado parcial explicitado",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/analyses/recurrence": {
      "post": {
        "operationId": "createRecurrenceAnalysis",
        "x-required-scope": "analytics:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Idempotency"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "input",
                  "quote_id",
                  "max_credits"
                ],
                "properties": {
                  "input": {
                    "$ref": "#/components/schemas/RecurrenceInput"
                  },
                  "quote_id": {
                    "type": "string"
                  },
                  "max_amount_brl": {
                    "type": "number",
                    "minimum": 0,
                    "deprecated": true
                  },
                  "max_credits": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Créditos de serviço; 1 crédito = R$0,01 nesta versão."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Análise assíncrona; resultado com contagens, denominadores, cobertura e abstenção",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/certifications/{id}": {
      "get": {
        "operationId": "getCertification",
        "x-required-scope": "evidence:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "Estado atual, inclusive revogação; sem custo para objeto autorizado",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "object_id",
                    "object_revision",
                    "status",
                    "policy_version",
                    "scope",
                    "issued_at",
                    "evidence",
                    "reviewer_ref",
                    "dependency_digest"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "object_id": {
                      "type": "string"
                    },
                    "object_revision": {
                      "type": "integer",
                      "minimum": 1
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "active",
                        "revoked",
                        "superseded"
                      ]
                    },
                    "policy_version": {
                      "type": "string"
                    },
                    "scope": {
                      "type": "array",
                      "minItems": 1,
                      "items": {
                        "type": "string"
                      }
                    },
                    "issued_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "reviewer_ref": {
                      "type": "string",
                      "description": "Identificador auditável do responsável; sem dados pessoais"
                    },
                    "dependency_digest": {
                      "type": "string",
                      "pattern": "^[a-f0-9]{64}$"
                    },
                    "reason": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "evidence": {
                      "type": "array",
                      "minItems": 1,
                      "items": {
                        "$ref": "#/components/schemas/SourceRef"
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/changes": {
      "get": {
        "operationId": "listChanges",
        "x-required-scope": "changes:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "Feed autorizado; cursor inicial cria baseline, expirado retorna 410 e requer snapshot",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "events",
                    "next_cursor"
                  ],
                  "properties": {
                    "events": {
                      "type": "array",
                      "items": {
                        "$ref": "./event.schema.json"
                      }
                    },
                    "next_cursor": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "410": {
            "$ref": "#/components/responses/Error"
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/usage": {
      "get": {
        "operationId": "getUsage",
        "x-required-scope": "billing:read",
        "parameters": [
          {
            "name": "month",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Agregados reconciliáveis; montantes inteiros em microcentavos BRL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "currency",
                    "entries"
                  ],
                  "properties": {
                    "currency": {
                      "type": "string",
                      "const": "BRL"
                    },
                    "entries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "sku",
                          "quantity",
                          "amount_microcents",
                          "price_version",
                          "credits"
                        ],
                        "properties": {
                          "sku": {
                            "type": "string"
                          },
                          "quantity": {
                            "type": "number",
                            "minimum": 0
                          },
                          "amount_microcents": {
                            "type": "integer"
                          },
                          "price_version": {
                            "type": "string"
                          },
                          "credits": {
                            "type": "number",
                            "description": "Ajustes podem ser negativos; BRL equivalente não é débito adicional."
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/classification-jobs": {
      "post": {
        "operationId": "createClassificationJob",
        "summary": "Classificar prova contra edital/cargo com abstenção",
        "x-required-scope": "classification:write",
        "parameters": [
          {
            "$ref": "#/components/parameters/Idempotency"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "input",
                  "quote_id",
                  "max_credits"
                ],
                "properties": {
                  "input": {
                    "$ref": "#/components/schemas/ClassificationInput"
                  },
                  "quote_id": {
                    "type": "string"
                  },
                  "max_credits": {
                    "type": "number",
                    "minimum": 0,
                    "description": "Créditos de serviço; 1 crédito = R$0,01 nesta versão."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Aceito; não é declaração de aderência ou anulação",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/wallet": {
      "get": {
        "operationId": "getWallet",
        "x-required-scope": "billing:read",
        "responses": {
          "200": {
            "description": "Saldo e reserva auditáveis; sem cartão",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "available_credits",
                    "reserved_credits",
                    "brl_per_credit",
                    "price_version"
                  ],
                  "properties": {
                    "available_credits": {
                      "type": "number",
                      "minimum": 0,
                      "description": "Créditos de serviço; 1 crédito = R$0,01 nesta versão."
                    },
                    "reserved_credits": {
                      "type": "number",
                      "minimum": 0,
                      "description": "Créditos de serviço; 1 crédito = R$0,01 nesta versão."
                    },
                    "brl_per_credit": {
                      "type": "number",
                      "const": 0.01
                    },
                    "price_version": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/uploads": {
      "post": {
        "operationId": "createUpload",
        "summary": "Preparar upload privado de PDF para URL temporária",
        "x-required-scope": "uploads:write",
        "parameters": [
          {
            "$ref": "#/components/parameters/Idempotency"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Upload pendente; PUT na URL sem chave de API, com headers retornados",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Upload"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/uploads/{id}/complete": {
      "post": {
        "operationId": "completeUpload",
        "summary": "Finalizar upload e iniciar validações de arquivo/hash",
        "x-required-scope": "uploads:write",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          },
          {
            "$ref": "#/components/parameters/Idempotency"
          }
        ],
        "responses": {
          "202": {
            "description": "Verificação iniciada; consultar GET /uploads/{id}",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Upload"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/uploads/{id}": {
      "get": {
        "operationId": "getUpload",
        "summary": "Consultar estado da validação do PDF",
        "x-required-scope": "uploads:read",
        "parameters": [
          {
            "$ref": "#/components/parameters/Id"
          }
        ],
        "responses": {
          "200": {
            "description": "Somente ready pode ser usado em jobs",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Upload"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Chave opaca server-to-server; nunca chave service_role"
      }
    },
    "parameters": {
      "ReadIdempotency": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string",
          "minLength": 16,
          "maxLength": 128
        },
        "description": "Opcional em leitura faturável; retry da mesma operação e parâmetros reaproveita recibo e snapshot por 48h. Chave com parâmetros diferentes retorna 409. Sem chave, cada leitura é independente. Revogação de direitos prevalece sobre replay."
      },
      "Id": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "minLength": 1
        }
      },
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "schema": {
          "type": "string"
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 20
        }
      },
      "Idempotency": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string",
          "minLength": 16,
          "maxLength": 128
        },
        "description": "Mesmo tenant, operação, chave e payload reaproveitam resultado por pelo menos 48 horas"
      }
    },
    "responses": {
      "Error": {
        "description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "type": "object",
              "required": [
                "type",
                "title",
                "status",
                "code",
                "request_id"
              ],
              "properties": {
                "type": {
                  "type": "string",
                  "format": "uri"
                },
                "title": {
                  "type": "string"
                },
                "status": {
                  "type": "integer",
                  "minimum": 400,
                  "maximum": 599
                },
                "code": {
                  "type": "string"
                },
                "request_id": {
                  "type": "string"
                },
                "detail": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "DocumentJobInput": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "upload_ids",
          "task",
          "quality_policy"
        ],
        "properties": {
          "upload_ids": {
            "type": "array",
            "minItems": 1,
            "maxItems": 10,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "minLength": 1
            },
            "description": "Uploads validados e imutáveis do tenant; tamanho e hash verificados no servidor"
          },
          "task": {
            "type": "string",
            "enum": [
              "extract_syllabus",
              "reconcile_documents"
            ]
          },
          "position_id": {
            "type": "string"
          },
          "quality_policy": {
            "type": "string",
            "enum": [
              "extracted",
              "documentary_certified"
            ]
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "task": {
                  "const": "extract_syllabus"
                }
              }
            },
            "then": {
              "required": [
                "position_id"
              ]
            }
          }
        ]
      },
      "RecurrenceInput": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "position_id",
          "syllabus_revision",
          "date_from",
          "date_to"
        ],
        "properties": {
          "position_id": {
            "type": "string"
          },
          "syllabus_revision": {
            "type": "integer",
            "minimum": 1
          },
          "date_from": {
            "type": "string",
            "format": "date"
          },
          "date_to": {
            "type": "string",
            "format": "date"
          },
          "board_id": {
            "type": "string"
          }
        },
        "description": "Servidor valida intervalo e congela população/taxonomia na cotação; mudança de dependência exige nova cotação"
      },
      "SourceRef": {
        "type": "object",
        "required": [
          "document_version_id",
          "sha256",
          "locator"
        ],
        "properties": {
          "document_version_id": {
            "type": "string"
          },
          "sha256": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "page": {
            "type": "integer",
            "minimum": 1
          },
          "locator": {
            "type": "string",
            "minLength": 1
          },
          "source_url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "Quality": {
        "type": "object",
        "required": [
          "documentary_status",
          "semantic_status",
          "currentness",
          "certificate_ids"
        ],
        "allOf": [
          {
            "if": {
              "anyOf": [
                {
                  "properties": {
                    "documentary_status": {
                      "const": "certified"
                    }
                  }
                },
                {
                  "properties": {
                    "semantic_status": {
                      "const": "certified"
                    }
                  }
                }
              ]
            },
            "then": {
              "properties": {
                "certificate_ids": {
                  "minItems": 1
                }
              }
            }
          }
        ],
        "properties": {
          "documentary_status": {
            "type": "string",
            "enum": [
              "candidate",
              "reviewed",
              "certified",
              "rejected"
            ]
          },
          "semantic_status": {
            "type": "string",
            "enum": [
              "not_assessed",
              "candidate",
              "certified",
              "abstained",
              "rejected"
            ]
          },
          "currentness": {
            "type": "string",
            "enum": [
              "current",
              "superseded",
              "conflicted",
              "unknown"
            ]
          },
          "certificate_ids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "Question": {
        "type": "object",
        "required": [
          "id",
          "revision",
          "statement",
          "style",
          "choices",
          "answer",
          "provenance",
          "quality",
          "license_id",
          "origin",
          "exam_id",
          "board_id",
          "year",
          "semantic_mappings",
          "assets"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "revision": {
            "type": "integer",
            "minimum": 1
          },
          "statement": {
            "type": "string"
          },
          "style": {
            "type": "string",
            "enum": [
              "multiple_choice",
              "true_false",
              "other"
            ]
          },
          "choices": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "text"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "text": {
                  "type": "string"
                }
              }
            }
          },
          "answer": {
            "type": "object",
            "required": [
              "revision",
              "status",
              "correct_choice_ids"
            ],
            "properties": {
              "revision": {
                "type": "integer",
                "minimum": 1
              },
              "status": {
                "type": "string",
                "enum": [
                  "unknown",
                  "preliminary",
                  "final",
                  "annulled"
                ]
              },
              "correct_choice_ids": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "provenance": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SourceRef"
            }
          },
          "quality": {
            "$ref": "#/components/schemas/Quality"
          },
          "license_id": {
            "type": "string"
          },
          "origin": {
            "type": "string",
            "enum": [
              "official_exam",
              "client_owned",
              "synthetic"
            ]
          },
          "exam_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "board_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "year": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1900
          },
          "semantic_mappings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SemanticMapping"
            }
          },
          "assets": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "url",
                "expires_at",
                "sha256",
                "media_type",
                "alt_text"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "expires_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "sha256": {
                  "type": "string",
                  "pattern": "^[a-f0-9]{64}$"
                },
                "media_type": {
                  "type": "string"
                },
                "alt_text": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          }
        }
      },
      "SemanticMapping": {
        "type": "object",
        "required": [
          "id",
          "concept_id",
          "taxonomy_revision",
          "position_id",
          "syllabus_revision",
          "relation",
          "status",
          "certificate_id",
          "evidence"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "concept_id": {
            "type": "string"
          },
          "taxonomy_revision": {
            "type": "integer",
            "minimum": 1
          },
          "position_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "syllabus_revision": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          },
          "relation": {
            "type": "string",
            "enum": [
              "assesses",
              "maps_to",
              "broader_than",
              "narrower_than",
              "equivalent_to"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "candidate",
              "certified",
              "rejected",
              "abstained"
            ]
          },
          "certificate_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "evidence": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SourceRef"
            }
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "status": {
                  "const": "certified"
                }
              }
            },
            "then": {
              "properties": {
                "certificate_id": {
                  "type": "string",
                  "minLength": 1
                },
                "evidence": {
                  "minItems": 1
                }
              }
            }
          }
        ]
      },
      "QuestionPage": {
        "type": "object",
        "required": [
          "items",
          "snapshot_id",
          "next_cursor",
          "changes_cursor",
          "usage_receipt_id"
        ],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Question"
            }
          },
          "snapshot_id": {
            "type": "string"
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "changes_cursor": {
            "type": "string",
            "description": "Watermark capturado atomicamente com snapshot; iniciar feed após completar paginação para não perder mudanças"
          },
          "usage_receipt_id": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Node": {
        "type": "object",
        "required": [
          "id",
          "revision",
          "parent_id",
          "label",
          "literal_text",
          "provenance",
          "quality",
          "applicable_position_ids",
          "semantic_mappings"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "revision": {
            "type": "integer",
            "minimum": 1
          },
          "parent_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "label": {
            "type": "string"
          },
          "literal_text": {
            "type": [
              "string",
              "null"
            ]
          },
          "applicable_position_ids": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string"
            }
          },
          "semantic_mappings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SemanticMapping"
            }
          },
          "provenance": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SourceRef"
            }
          },
          "quality": {
            "$ref": "#/components/schemas/Quality"
          }
        }
      },
      "Job": {
        "type": "object",
        "required": [
          "id",
          "status",
          "result",
          "error",
          "usage_receipt_id"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "processing",
              "review_required",
              "completed",
              "partial",
              "failed",
              "cancelled"
            ]
          },
          "result": {
            "type": [
              "object",
              "null"
            ],
            "required": [
              "artifact_id",
              "revision",
              "download_url",
              "expires_at",
              "artifact_type"
            ],
            "description": "Ponteiro para artefato versionado autorizado; resultado analítico usa schema RecurrenceResult",
            "properties": {
              "artifact_id": {
                "type": "string"
              },
              "revision": {
                "type": "integer",
                "minimum": 1
              },
              "download_url": {
                "type": "string",
                "format": "uri"
              },
              "expires_at": {
                "type": "string",
                "format": "date-time"
              },
              "artifact_type": {
                "type": "string",
                "enum": [
                  "documentary",
                  "recurrence",
                  "classification"
                ]
              }
            }
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "usage_receipt_id": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "RecurrenceResult": {
        "type": "object",
        "required": [
          "snapshot_id",
          "taxonomy_revision",
          "population_count",
          "eligible_count",
          "coverage_ratio",
          "abstained",
          "topics"
        ],
        "properties": {
          "snapshot_id": {
            "type": "string"
          },
          "taxonomy_revision": {
            "type": "integer",
            "minimum": 1
          },
          "population_count": {
            "type": "integer",
            "minimum": 0
          },
          "eligible_count": {
            "type": "integer",
            "minimum": 0
          },
          "coverage_ratio": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "abstained": {
            "type": "boolean"
          },
          "topics": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "concept_id",
                "count",
                "denominator"
              ],
              "properties": {
                "concept_id": {
                  "type": "string"
                },
                "count": {
                  "type": "integer",
                  "minimum": 0
                },
                "denominator": {
                  "type": "integer",
                  "minimum": 0
                },
                "frequency": {
                  "type": [
                    "number",
                    "null"
                  ],
                  "minimum": 0,
                  "maximum": 1
                }
              }
            }
          }
        }
      },
      "ClassificationInput": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "edict_upload_id",
          "exam_upload_id",
          "answer_key_upload_id",
          "position_label",
          "sharing_mode"
        ],
        "properties": {
          "edict_upload_id": {
            "type": "string"
          },
          "exam_upload_id": {
            "type": "string"
          },
          "answer_key_upload_id": {
            "type": "string"
          },
          "position_label": {
            "type": "string",
            "minLength": 1
          },
          "sharing_mode": {
            "type": "string",
            "enum": [
              "private",
              "public_contribution"
            ]
          },
          "rights_attestation_id": {
            "type": "string"
          },
          "language": {
            "type": "string",
            "default": "pt-BR"
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "sharing_mode": {
                  "const": "public_contribution"
                }
              }
            },
            "then": {
              "required": [
                "rights_attestation_id"
              ]
            }
          }
        ],
        "description": "Uploads autorizados e cargo obrigatório; contribuição exige direitos compatíveis. Extração/programa novos são componentes do orçamento, sem duplicidade."
      },
      "ClassificationResult": {
        "type": "object",
        "required": [
          "job_id",
          "model_version",
          "syllabus_revision",
          "expected_items",
          "extracted_items",
          "items"
        ],
        "properties": {
          "job_id": {
            "type": "string"
          },
          "model_version": {
            "type": "string"
          },
          "syllabus_revision": {
            "type": "integer",
            "minimum": 1
          },
          "expected_items": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "extracted_items": {
            "type": "integer",
            "minimum": 0
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "question_id",
                "status",
                "mappings",
                "evidence"
              ],
              "properties": {
                "question_id": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "supported_match",
                    "ambiguous",
                    "no_supported_match",
                    "insufficient_extraction",
                    "review_required"
                  ]
                },
                "mappings": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SemanticMapping"
                  }
                },
                "evidence": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SourceRef"
                  }
                }
              }
            }
          }
        },
        "description": "no_supported_match é indício para revisão, não conclusão jurídica."
      },
      "UploadRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "purpose",
          "content_type",
          "byte_size",
          "sha256"
        ],
        "properties": {
          "purpose": {
            "type": "string",
            "enum": [
              "edict",
              "exam",
              "answer_key",
              "private_corpus"
            ]
          },
          "content_type": {
            "const": "application/pdf"
          },
          "byte_size": {
            "type": "integer",
            "minimum": 1,
            "maximum": 26214400
          },
          "sha256": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          }
        }
      },
      "Upload": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "status",
          "expires_at"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "verifying",
              "ready",
              "rejected"
            ]
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "put_url": {
            "type": "string",
            "format": "uri"
          },
          "required_headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "reason": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "status": {
                  "const": "pending"
                }
              }
            },
            "then": {
              "required": [
                "put_url",
                "required_headers"
              ]
            }
          }
        ]
      }
    }
  }
}
