# D&D NPC Artifact This document defines the durable D&D NPC-list artifact and its JSON codec. The artifact type and codec are implemented, but no selectable production pipeline currently produces this artifact. ## Identity - Artifact kind: `dnd/npc-list` - Durable schema ID: `notarius.dnd.npcs` - Durable schema name: `notarius_dnd_npcs_v1` - Durable schema version: `v1` - Media type: `application/json` - Identity policy: `dnd.npcs.identity.v1` The durable JSON Schema is owned by the D&D NPC codec. NPC IDs are derived from the Unicode-normalized, case-folded canonical name using the identity policy. The durable codec enforces the artifact shape and ID syntax; registry identity validation remains a separate deterministic concern. ## Output Shape The payload is one object with a required top-level `npcs` array: ```json {"npcs": []} ``` The array may be empty. Every object and nested object rejects unknown fields. ## NPC Fields Each NPC contains exactly these required fields: - `id`: `npc:sha256:` followed by 64 lowercase hexadecimal characters; - `name`: the canonical display name; - `aliases`: an array of alternate display names, which may be empty; - `description`: a concise description; - `relationships`: an array of target/relationship objects, which may be empty; - `source_refs`: at least one source reference supporting the NPC record. Each relationship contains required `target` and `relationship` strings. Each source reference contains required `source_id`, `start_unit_id`, and `end_unit_id`; unit IDs are positive integers. Source document identity, unit existence, and range ordering are validated by the source-reference validator when the artifact is used by a pipeline. ## Codec Boundary `EncodeCandidate` and `DecodeCandidate` provide strict single-value JSON serialization while preserving typed values that still need semantic validation. `Encode` and `Decode` are the approved-artifact boundary and require all durable structural fields, non-empty required strings, valid source reference shapes, and the NPC ID pattern. Codec metadata contains only `npc_count`. Schema bytes and returned metadata are independent values so callers cannot mutate codec-owned state.