# D&D Scene Description Artifact Contract This document defines the durable `dnd/scene-description-list` artifact emitted by the D&D scene-description lane. ## Artifact identity | Property | Value | | --- | --- | | Artifact kind | `dnd/scene-description-list` | | Schema ID | `notarius.dnd.scene_descriptions` | | Schema name | `notarius_dnd_scene_descriptions_v1` | | Schema version | `v1` | | Media type | `application/json` | The normalized payload is written by the JSON output module to `lanes/.json`. See [JSON output](json-output.md) for the surrounding output bundle. ## JSON shape The payload is a JSON object containing exactly one required field, `scenes`. Each scene object contains exactly these required fields: | Field | Shape and ownership | | --- | --- | | `id` | Non-empty accepted chunk ID, assigned by Notarius. | | `source_ref` | Exact inclusive accepted chunk range, assigned by Notarius. | | `kind` | One of `combat`, `narrative`, `recap`, or `meta`. | | `title` | Non-empty, trimmed, source-grounded title. | | `summary` | Non-empty, trimmed, source-grounded summary. | All object layers reject unknown fields. The `scenes` array must be present and non-empty. `source_ref` has exactly `source_id`, `start_unit_id`, and `end_unit_id`; its source ID is non-empty and its unit IDs are positive integers. ```json { "scenes": [ { "id": "chunk-000001", "source_ref": { "source_id": "session-alpha", "start_unit_id": 1, "end_unit_id": 3 }, "kind": "narrative", "title": "Arrival at the watchtower", "summary": "The party reaches the ruined watchtower and begins to investigate it." } ] } ``` `id` and `source_ref` are application-owned identity and evidence. The model provides only `kind`, `title`, and `summary`; it is not asked for chunk IDs, source IDs, unit IDs, ranges, participants, or confidence. ## Scene kinds | Kind | Meaning | | --- | --- | | `combat` | Active combat is a substantive central activity. | | `narrative` | Current-session in-world play that is not principally combat, recap, or meta discussion. | | `recap` | The table is primarily recounting a previous session. | | `meta` | Sustained out-of-character discussion is the scene's primary purpose. | For a mixed accepted chunk, classification prefers `combat`, then `recap`, then `meta`, then `narrative`. Brief table talk, rules clarification, or a short recollection does not replace the main current-session activity. ## Extraction and evidence The extractor runs once for each accepted chunk and maps one successful model response to one scene record. It copies the current chunk ID and exact chunk range, preserves the model kind without repair, and trims only surrounding whitespace from title and summary. A model response cannot represent an empty result; extraction failure follows the configured retry and rejection policy. Optional `players`, `party`, and `glossary` campaign references can help disambiguate names or setting terms. They never supply scene evidence or add events absent from the accepted chunk. The lane requires no NPC registry or other generated artifact reference. ## Merge and normalization Accepted per-chunk lists are appended in chunk order. Normalization then: 1. validates the current-source range, non-empty ID and prose, and closed kind; 2. trims only title and summary whitespace; 3. sorts records by source-document start position, then ID; 4. removes records only when all five durable fields are identical; 5. rejects a reused ID when any remaining durable field differs; and 6. rejects the same exact range when `kind`, `title`, or `summary` differs. Two different IDs with the same range and identical model-owned content remain separate records. Normalization does not join adjacent ranges, rewrite prose, repair kinds, infer missing scenes, or use chunk annotations. ## Validation and warnings Extraction validation requires exactly one record with an ID and range exactly equal to its current chunk. Later validation checks source membership without a current chunk. Shape, source-range, kind, ID, and normalized-invariant failures reject the artifact. Relatedness checks are advisory. They separately warn when a scene title or summary has no significant lexical token in its cited transcript range. The check ignores short tokens and common function words, uses transcript text only, and does not treat campaign references as evidence. Warning diagnostics are bounded and do not copy transcript or campaign-reference content. ## Configuration Use `dnd/scenes` to form accepted scene chunks, then select `dnd/scene-descriptions` for extraction and normalization. The maintained [complete D&D configuration](../../examples/dnd-complete.config.yml) includes this lane alongside the other D&D artifacts. Selectable keys and default validator chains are defined in [Configuration](../config.md). ## Downstream combat use The combat-turn extractor consumes this approved artifact as required eligibility control context through an explicit ordered reference binding. It uses only an exact chunk ID and source-range match with `kind: combat` to permit combat extraction; titles, summaries, and scene references do not become combat prompt material or evidence. The complete downstream behavior, including empty results and warnings for unavailable coverage, is defined in the [D&D combat-turn artifact contract](dnd-combat-turn-artifacts.md).