Files
research/md/demonology/demons.schema.json
ptarrant 2ea33cff61 Add per-topic structured fact-cache pattern, validator, and docs
Introduce a machine-readable layer on top of the markdown corpus so AI/scripts
can query a topic's facts without re-reading whole sources (anti-RAG stays for
synthesis/quotes).

- md/demonology/demons.json: fact-cache, 33 entities attested in 2+ sources,
  each with rank/domain/signs/origins + provenance (sources, citations).
- md/demonology/demons.schema.json: JSON Schema for the dataset.
- md/demonology/INDEX.md: topic front-door (query JSON -> synthesis -> source).
- validate.py: generic schema + house-rule validator (source_count, cross_refs,
  unique ids); discovers <name>.schema.json/<name>.json pairs across all topics.
- docs/data-convention.md: the reusable, topic-agnostic pattern + how to add it
  to a new topic.
- CLAUDE.md: pointer so the convention is picked up every session.
- requirements.txt: add jsonschema (used by validate.py).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 19:56:54 -05:00

139 lines
5.2 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://demonology.local/demons.schema.json",
"title": "Demonology Entity Dataset",
"description": "Machine-readable roster of demonic entities cross-referenced across the source documents in md/demonology/. Each record is a fact-cache derived from whole-file reads of the sources, so AI agents can query attributes without re-reading the corpus. Scope: entities attested in 2 or more sources.",
"type": "object",
"required": ["meta", "sources", "demons"],
"properties": {
"meta": {
"type": "object",
"required": ["topic", "scope", "rank_ladder", "generated_from"],
"properties": {
"topic": { "type": "string" },
"scope": {
"type": "string",
"description": "Inclusion rule for this dataset, e.g. 'entities attested in 2+ sources'."
},
"rank_ladder": {
"type": "array",
"description": "Classical grimoire ranks, highest authority first.",
"items": { "type": "string" }
},
"generated_from": {
"type": "array",
"description": "Sibling files this data was derived from / kept in sync with.",
"items": { "type": "string" }
},
"caveat": { "type": "string" }
}
},
"sources": {
"type": "object",
"description": "Map of source code -> human-readable source description. Codes are used in each demon's 'sources' array.",
"patternProperties": {
"^[A-Z]{2}$": { "type": "string" }
},
"additionalProperties": false
},
"demons": {
"type": "array",
"items": { "$ref": "#/$defs/demon" }
}
},
"$defs": {
"sourceCode": {
"type": "string",
"enum": ["FG", "DM", "PU", "SP", "DJ", "EN"]
},
"demon": {
"type": "object",
"required": ["id", "name", "type", "tier", "domain", "signs", "origins", "sources", "source_count", "citations"],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"pattern": "^[a-z0-9-]+$",
"description": "Stable kebab-case identifier; used as the target of cross_refs."
},
"name": { "type": "string", "description": "Primary / most common name." },
"aliases": {
"type": "array",
"items": { "type": "string" }
},
"type": {
"type": "string",
"enum": ["individual", "collective", "class", "title"],
"description": "individual = a single named entity; collective = a named group acting as one (e.g. Legion); class = a category of spirits (e.g. Shedim); title = an honorific/role applied to others."
},
"tier": {
"type": "string",
"enum": ["supreme-prince", "directional-king", "goetia-officer", "watcher", "other-recurring"],
"description": "Which sub-hierarchy this entity belongs to in the synthesis."
},
"rank": {
"type": ["string", "null"],
"description": "Grimoire rank as stated (King, Duke, Prince, Marquis, Earl, President, Knight, Emperor, etc.). Null if none stated."
},
"legions": {
"type": ["integer", "null"],
"description": "Number of legions commanded, if stated."
},
"goetia_number": {
"type": ["integer", "null"],
"minimum": 1,
"maximum": 72,
"description": "Position among the 72 Spirits of the Ars Goetia, if applicable."
},
"deadly_sin": {
"type": ["string", "null"],
"description": "Associated deadly sin, for the seven Princes of Hell scheme."
},
"domain": {
"type": "array",
"description": "Spheres of influence / what it governs.",
"items": { "type": "string" }
},
"signs": {
"type": "array",
"description": "Identifying marks: apparition form, associations, sigils, manner of manifesting.",
"items": { "type": "string" }
},
"origins": {
"type": "string",
"description": "Etymology, backstory, derivation from earlier deities/traditions."
},
"sources": {
"type": "array",
"minItems": 2,
"uniqueItems": true,
"items": { "$ref": "#/$defs/sourceCode" },
"description": "Source codes that name this entity. Scope rule requires length >= 2."
},
"source_count": {
"type": "integer",
"minimum": 2,
"description": "Number of distinct sources; must equal sources.length."
},
"citations": {
"type": "object",
"description": "Map of source code -> location string within that source file.",
"patternProperties": {
"^[A-Z]{2}$": { "type": "string" }
},
"additionalProperties": false
},
"cross_refs": {
"type": "array",
"description": "ids of entities this one is identified/conflated with, or commands/serves.",
"items": { "type": "string", "pattern": "^[a-z0-9-]+$" }
},
"notes": {
"type": ["string", "null"],
"description": "Uncertainty flags, conflation warnings, or scope caveats."
}
}
}
}
}