{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "urn:tacitus:schema:capsule:1",
  "title": "Tacitus portable context capsule",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "format",
    "capsule_id",
    "compiler_version",
    "ontology_version",
    "task",
    "sources",
    "spans",
    "units",
    "selection",
    "review_status",
    "limitations"
  ],
  "properties": {
    "format": {
      "const": "tacitus-capsule/1"
    },
    "capsule_id": {
      "type": "string",
      "pattern": "^sha256:[0-9a-f]{64}$"
    },
    "compiler_version": {
      "type": "string"
    },
    "ontology_version": {
      "type": "string"
    },
    "task": {
      "type": "object",
      "required": [
        "question",
        "as_of"
      ],
      "additionalProperties": false,
      "properties": {
        "question": {
          "type": "string",
          "minLength": 1
        },
        "as_of": {
          "type": "string",
          "format": "date"
        }
      }
    },
    "sources": {
      "type": "array",
      "minItems": 1,
      "maxItems": 256,
      "items": {
        "type": "object",
        "required": [
          "id",
          "title",
          "url",
          "published_on",
          "version",
          "offset_unit",
          "rights",
          "access_tags"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1
          },
          "title": {
            "type": "string",
            "minLength": 1
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "published_on": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "collected_on": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "valid_from": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "expires_on": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "version": {
            "type": "string",
            "pattern": "^[0-9a-f]{64}$"
          },
          "offset_unit": {
            "const": "UTF-16 code units"
          },
          "rights": {
            "type": "object",
            "required": [
              "citable",
              "note"
            ],
            "properties": {
              "citable": {
                "const": true
              },
              "note": {
                "type": "string"
              }
            }
          },
          "access_tags": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string"
            }
          }
        }
      }
    },
    "spans": {
      "type": "array",
      "minItems": 1,
      "maxItems": 1024,
      "items": {
        "type": "object",
        "required": [
          "id",
          "source_id",
          "start",
          "end",
          "quote",
          "locator"
        ],
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1
          },
          "source_id": {
            "type": "string",
            "minLength": 1
          },
          "start": {
            "type": "integer",
            "minimum": 0
          },
          "end": {
            "type": "integer",
            "minimum": 1
          },
          "quote": {
            "type": "string",
            "minLength": 1
          },
          "locator": {
            "type": "string",
            "minLength": 1
          }
        }
      }
    },
    "units": {
      "type": "array",
      "minItems": 1,
      "maxItems": 1024,
      "items": {
        "type": "object",
        "required": [
          "id",
          "source_id",
          "start",
          "end",
          "locator",
          "label",
          "claim",
          "dependencies",
          "qualifications",
          "topics",
          "review_state",
          "evidence_id"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1
          },
          "source_id": {
            "type": "string",
            "minLength": 1
          },
          "start": {
            "type": "integer",
            "minimum": 0
          },
          "end": {
            "type": "integer",
            "minimum": 1
          },
          "locator": {
            "type": "string",
            "minLength": 1
          },
          "label": {
            "type": "string",
            "minLength": 1
          },
          "claim": {
            "type": "object",
            "required": [
              "actor",
              "subject_type",
              "relation",
              "verb",
              "object",
              "object_type",
              "statement",
              "modality",
              "polarity"
            ],
            "properties": {
              "actor": {
                "type": "string",
                "minLength": 1
              },
              "subject_type": {
                "type": "string",
                "minLength": 1
              },
              "relation": {
                "type": "string",
                "minLength": 1
              },
              "verb": {
                "type": "string",
                "minLength": 1
              },
              "object": {
                "type": "string",
                "minLength": 1
              },
              "object_type": {
                "type": "string",
                "minLength": 1
              },
              "statement": {
                "type": "string",
                "minLength": 1
              },
              "modality": {
                "type": "string",
                "minLength": 1
              },
              "polarity": {
                "type": "string",
                "minLength": 1
              }
            }
          },
          "dependencies": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string",
              "minLength": 1
            }
          },
          "qualifications": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "topics": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "review_state": {
            "enum": [
              "not_reviewed",
              "needs_source_check"
            ]
          },
          "evidence_id": {
            "type": "string",
            "minLength": 1
          }
        }
      }
    },
    "selection": {
      "type": "object",
      "required": [
        "method",
        "method_note",
        "reasons",
        "omissions"
      ],
      "properties": {
        "method": {
          "enum": [
            "bm25",
            "hybrid",
            "source-order",
            "external"
          ]
        },
        "method_note": {
          "type": "string"
        },
        "reasons": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "unit_id",
              "reason",
              "matched_terms",
              "rank",
              "score"
            ]
          }
        },
        "omissions": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "unit_id",
              "reason"
            ]
          }
        }
      }
    },
    "review_status": {
      "const": "not_reviewed"
    },
    "limitations": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "description": "Structural validation; source verification and human review are separate."
}
