# D&D Spell-Catalog Overlay Contract This document defines the JSON format accepted by the D&D spell catalog resolver. An overlay supplies campaign-specific spell names and aliases for recognition. It does not supply spell rules, levels, classes, effects, or source evidence. The `dnd/spells` extractor accepts one optional UTF-8 `application/json` overlay bundle through its `spell_catalog` reference slot. The framework materializes that file relative to the configuration or command-line binding, enforces the 1 MiB slot limit, and records its origin and raw digest separately from the effective catalog digest. ## Shape An overlay bundle has this shape: ```json { "schema_version": "notarius.dnd.spell-catalog-overlay.v1", "catalogs": [ { "id": "campaign.example", "ruleset": "dnd-5e-2014", "source": { "title": "Example campaign spells", "version": "1", "url": "", "license": "" }, "spells": [ { "name": "Aegis of Emberfall", "aliases": ["Emberfall Aegis"] } ] } ] } ``` The top-level `schema_version` and `catalogs` fields are required. The schema version must be exactly `notarius.dnd.spell-catalog-overlay.v1`, and at least one catalog is required. Catalogs require a unique, non-empty, trimmed `id`, the exact `dnd-5e-2014` `ruleset`, a `source`, and a non-empty `spells` array. `source.title` is required and must be non-empty and trimmed. `source.version`, `source.url`, and `source.license` are optional strings and may be empty. Each spell requires a non-empty, trimmed `name`. `aliases` may be omitted or may be an array of trimmed, non-empty strings; JSON `null` is not an alias array. Overlay objects contain no other supported spell fields. Decoding is strict: unknown fields, malformed JSON, trailing JSON values, and non-string optional source fields are rejected. ## Composition The resolver always starts with the embedded D&D 5e 2014 SRD catalog. Overlay catalogs are sorted by `id` before composition, so the input order does not affect the result. A new canonical name adds a recognition entry. A canonical name matching an existing canonical name augments that spell and keeps the established canonical display spelling. Repeated aliases for the same spell are idempotent. Canonical-name display conflicts and canonical/alias or alias/alias collisions between different spells are errors, including collisions with the embedded catalog. Canonical names and aliases use the catalog's case, whitespace, and common-apostrophe normalization rules. The effective catalog returns canonical names in sorted order and produces a semantic SHA-256 digest that is stable under JSON formatting, object-key, catalog, spell, and alias reordering.