# D&D Module Internals This guide records the conventions shared by the production D&D module family. It complements [Module Internals](modules.md), which owns generic registration and extension mechanics, and [Configuration](../config.md), which owns the selectable keys, bindings, reference syntax, and default validator chains. ## Durable Artifact Contracts The six lanes have separate durable wire contracts. This guide deliberately does not repeat their JSON shapes or schemas. | Lane | Durable contract | | --- | --- | | Spells | [spell artifacts](../integrations/dnd-spell-artifacts.md) | | NPCs | [NPC artifacts](../integrations/dnd-npc-artifacts.md) | | Combat turns | [combat-turn artifacts](../integrations/dnd-combat-turn-artifacts.md) | | Item events | [item-event artifacts](../integrations/dnd-item-event-artifacts.md) | | NPC interactions | [NPC-interaction artifacts](../integrations/dnd-npc-interaction-artifacts.md) | | Scene descriptions | [scene-description artifacts](../integrations/dnd-scene-description-artifacts.md) | ## Family Composition The D&D registrar registers the family’s artifact codecs, extractors, typed append-order mergers, normalizers, validators, prompt assets, and default validator chains. Each extractor and normalizer has a stable module spec, strict option decoding, and a typed builder. Configuration remains the canonical owner of the exact keys and validator order. Private structured-LLM response schemas are deliberately minimal. They reject invalid JSON structure, missing required fields, incompatible types, and unknown fields, while preserving semantic candidates for deterministic validation. Do not promote a private response envelope into a durable schema; the contracts above define durable data. ## Prompt Construction D&D extractors assemble prompts from an ordered manifest of shared and module-owned assets. Reuse the shared D&D system, evidence, identity, reference, and transcript assets instead of copying their text into individual modules. A manifest’s declared sequence, including cache-control placement, is part of the prompt behavior, and the chunk transcript is the final message. Preserve that order when changing an extractor or its assets so prompt-cache behavior remains stable. All extractors use the shared prompt-input preparation rules. The current chunk is copied into transcript material; player, party, glossary, and compatible campaign references are context for disambiguation, not source evidence. Reference prompt material is canonically ordered before it is rendered, which keeps equivalent inputs stable across runs. ## Evidence, Candidates, And Normalization The current transcript is the only durable evidence source. Extractors assign the current source identity, preserve candidate evidence ranges for validators, and canonically order or remove exact duplicate ranges without asking the model to repair semantic errors. Campaign context and generated artifacts may ground names or control routing, but they never establish evidence for a D&D result. Default chains keep responsibilities separate: structural validators assess the candidate, source-reference validators resolve cited ranges against the current source, durable-schema validation checks an approved representation, and relatedness validators report advisory evidence concerns. The configured order is documented in [Configuration](../config.md#production-validator-keys-and-default-chains). Normalizers are deterministic for spells, combat turns, item events, NPC interactions, and scene descriptions. They canonicalize display values and evidence, use source-document order for stable output, and issue bounded warnings for changes or collapsed duplicates. The NPC normalizer is the intentional exception: it first produces a deterministic candidate set, then uses a bounded structured-LLM proposal to reconcile identity groups. Invalid or unusable proposals retain the deterministic result and surface retry or fallback diagnostics; the model does not directly replace durable records. ## Generated References And Grounding Normalized D&D artifacts can be handed to a later step through a generated reference binding. The framework verifies artifact compatibility and retains producer provenance; consumers resolve the handed-off artifact into an immutable, validated projection for each operation. External files are checked during preparation, while generated artifacts are resolved at the handoff. NPC registries are names-only grounding projections: they may canonicalize actors for spells and combat turns and are required for NPC interactions, but they do not supply evidence. Scene-description registries are eligibility-only projections: they retain the current chunk’s classification data, not scene prose or evidence, and exist to route combat extraction. ## Lane-Specific Rules The following differences are intentional and should remain explicit when a shared helper changes. | Lane | Intentional behavior | | --- | --- | | Spells | May use a spell-catalog overlay and optional NPC grounding; the catalog validator supplies domain-specific semantic checks. | | NPCs | Does not consume an NPC registry. Its normalizer is the LLM-assisted reconciliation exception described above. | | Combat turns | Requires a scene-description artifact. It calls the LLM only for an exact `combat` classification; exact non-combat classifications return an accepted empty result, while missing or mismatched classifications return an empty result with a bounded warning. Optional NPC grounding never becomes evidence. | | Item events | Uses campaign context for disambiguation but has no NPC-registry or scene-description dependency. | | NPC interactions | Requires the normalized NPC registry at extraction and normalization, using it for canonical actor grounding only. | | Scene descriptions | Produces the classifications consumed by combat routing; it does not consume an NPC registry or provide evidence for combat artifacts. | The combat and scene-description contracts describe their exact handoff and empty-result behavior in more detail: [combat turns](../integrations/dnd-combat-turn-artifacts.md) and [scene descriptions](../integrations/dnd-scene-description-artifacts.md). ## Focused Verification When changing D&D behavior, test the affected codec, extractor, normalizer, validator, prompt-asset manifest, and registry projection. Also test generated handoffs at the integration boundary and run the full D&D module suite: ~~~sh go test ./internal/modules/dnd/... go test ./internal/modules/integration/... ~~~