{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://anthroposophy.ai/index/data/schema.json",
  "title": "index-entry/1.0",
  "description": "One entry of the subject index: a headword, its aliases in English and German, a stated selection principle, and sub-headings each listing the places in the Gesamtausgabe where the concept is treated. An entry carries no quotation and no interpretation; it says where to read. Every reference was verified against the served corpus at build time and names the edition it was verified in. Additive changes stay within 1.x; a breaking change moves the files to data/v2/.",
  "type": "object",
  "required": ["schema", "id", "headword", "aliases", "selection_principle", "usage", "sections", "see_also", "distinguish_from", "external", "counts", "generated"],
  "additionalProperties": false,
  "properties": {
    "schema": {"const": "index-entry/1.0"},
    "id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$", "description": "The entry's stable id and its URL stem: /index/<id>/ and /index/data/<id>.json."},
    "headword": {
      "type": "object",
      "required": ["en", "de"],
      "additionalProperties": false,
      "properties": {"en": {"type": "string", "minLength": 1}, "de": {"type": "string", "minLength": 1}}
    },
    "aliases": {
      "type": "object",
      "required": ["en", "de"],
      "additionalProperties": false,
      "properties": {
        "en": {"type": "array", "items": {"type": "string", "minLength": 1}},
        "de": {"type": "array", "items": {"type": "string", "minLength": 1}}
      },
      "description": "Other names for the same concept. An alias resolves to this entry; it never names a second concept. A name Steiner also uses, in a stated scheme, for a part of the concept is still an alias and carries an item in alias_notes."
    },
    "alias_notes": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["name", "lang", "note", "section"],
        "additionalProperties": false,
        "properties": {
          "name": {"type": "string", "minLength": 1, "description": "One of the aliases in that language, exactly as listed."},
          "lang": {"enum": ["en", "de"]},
          "note": {"type": "string", "minLength": 1, "maxLength": 400, "description": "Where the name means the whole concept and where a part of it. Names the works; makes no claim about what the passages say beyond the use of the name."},
          "section": {"type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$", "description": "The id of the section of this entry that lists the places stating the narrower use."}
        }
      },
      "description": "Qualifications of aliases whose use varies. An alias without an item here is used for the whole concept wherever it occurs."
    },
    "selection_principle": {"type": "string", "minLength": 1, "description": "What is particular to this entry's selection: what counts beside the headword, which volumes are listed whole, and where the headings come from. The rules every entry shares are in usage."},
    "usage": {"type": "string", "minLength": 1, "description": "The rules every entry follows, the same text in every entry: what is listed, in what order, in which language, and that the entry quotes nothing."},
    "sections": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": ["id", "heading", "refs"],
        "additionalProperties": false,
        "properties": {
          "id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$"},
          "heading": {"type": "string", "minLength": 1, "description": "The index's short name for the sub-topic, never Steiner's wording."},
          "scope": {"type": "string", "maxLength": 160, "description": "One line, beginning Where, saying which treatments the section lists. Optional. Never a claim about what the passages say."},
          "refs": {"type": "array", "minItems": 1, "items": {"$ref": "#/$defs/ref"}}
        }
      }
    },
    "see_also": {"type": "array", "items": {"$ref": "#/$defs/link"}},
    "distinguish_from": {"type": "array", "items": {"$ref": "#/$defs/link"}, "description": "Concepts the sources keep apart from this one. A reader who conflates them misreads the passages."},
    "external": {
      "type": "array",
      "description": "Reference pages about the concept on other sites, not texts by Steiner.",
      "items": {
        "type": "object",
        "required": ["label", "url"],
        "additionalProperties": false,
        "properties": {"label": {"type": "string", "minLength": 1, "description": "The site, named in full."}, "url": {"type": "string", "pattern": "^https://"}}
      }
    },
    "counts": {
      "type": "object",
      "description": "refs counts listings: a unit listed under several headings is counted each time.",
      "required": ["sections", "refs", "books", "articles", "lectures"],
      "additionalProperties": false,
      "properties": {
        "sections": {"type": "integer", "minimum": 1},
        "refs": {"type": "integer", "minimum": 1},
        "books": {"type": "integer", "minimum": 0},
        "articles": {"type": "integer", "minimum": 0},
        "lectures": {"type": "integer", "minimum": 0}
      }
    },
    "generated": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"}
  },
  "$defs": {
    "ref": {
      "type": "object",
      "required": ["locus", "ga", "volume", "unit", "lang", "edition", "kind", "title", "date", "url", "json_url", "verified"],
      "additionalProperties": false,
      "properties": {
        "locus": {"type": "string", "pattern": "^GA [0-9]+[a-z]?/[^/ ]+(/p[0-9]{3})?$", "description": "GA volume / unit id in the served edition, and the paragraph only where one passage is the point. The same form the site's verify endpoint accepts."},
        "ga": {"type": "string", "pattern": "^[0-9]+[a-z]?$", "description": "The GA volume number. A letter after it (266a, 68d) marks one part of a volume the site serves in parts."},
        "volume": {"type": "string", "description": "The title of the GA volume, as the site gives it; empty when the site has no volume page."},
        "unit": {"type": "string", "minLength": 1, "description": "The unit id as served: a date for a lecture (a second text on the same day carries _02), the edition's id for a chapter or essay. The id belongs to the edition named by lang: the German edition can serve the same chapter under another id, so one id in two languages can be two texts."},
        "lang": {"enum": ["en", "de"]},
        "edition": {"type": "string", "minLength": 1, "description": "The edition the unit was verified in for this language, as served: original for German, a translation code such as RSP1965 for English."},
        "kind": {"enum": ["book", "article", "lecture"], "description": "book: GA 1 to 28, his own written works. article: GA 29 to 46, essays, fragments and notes. lecture: everything else."},
        "passage": {"type": "integer", "minimum": 1, "description": "The paragraph number, present only where one passage is the point; otherwise the reference is the whole unit."},
        "title": {"type": "string", "description": "The unit's title as served. Filled from verification, never typed."},
        "date": {"type": ["string", "null"], "description": "YYYY-MM-DD for a lecture, and for an article or letter where the edition dates it; null for a book chapter."},
        "url": {"type": "string", "pattern": "^https://anthroposophy\\.ai/v1/", "description": "The page for the unit on the site."},
        "json_url": {"type": "string", "pattern": "^https://anthroposophy\\.ai/v1/.*\\.json$", "description": "The unit with its passages, or the one paragraph when passage is present, in the verified language. The same path with /de/ in place of /en/ returns the German where witnesses lists de:original."},
        "record_type": {"enum": ["listeners_notes", "own_manuscript", "report_by_others", "mixed_sources"], "description": "Present only where the publisher states how the volume was recorded, or the text's own heading says it is another person's report. listeners_notes means the wording is the note-taker's or reporter's as much as his; report_by_others means the text is another person's account of a meeting or event; mixed_sources means the volume holds both listeners' records and texts in Steiner's own hand (the esoteric lessons of GA 266c, for one), so the unit's own heading says which it is."},
        "verified": {
          "type": "object",
          "required": ["at", "exists", "witnesses"],
          "additionalProperties": false,
          "properties": {
            "at": {"type": "string"},
            "exists": {"const": true},
            "witnesses": {"type": "array", "minItems": 1, "items": {"type": "string"}, "description": "lang:edition for every edition in which the site holds the cited unit under this id (and, when passage is present, that paragraph under that number). An edition that numbers differently is not listed."},
            "passage_count": {"type": "integer", "minimum": 1, "description": "The unit's length in paragraphs, not a count of matches."},
            "may_be_abridged": {"type": "boolean", "description": "Present only when the site has compared the translation's length with the German; true means the translation is shorter. Absent means the site reports nothing."}
          }
        }
      }
    },
    "link": {
      "type": "object",
      "required": ["id", "label"],
      "additionalProperties": false,
      "properties": {
        "id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$"},
        "label": {"type": "string", "minLength": 1},
        "href": {"type": "string", "description": "Present only when an entry with that id exists; an id without one is reserved for an entry not yet made."}
      }
    }
  }
}
