156 lines
8.7 KiB
Markdown
156 lines
8.7 KiB
Markdown
# 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, fallback LLM
|
||
profile asset, and default validator chains. Each extractor and normalizer has
|
||
a stable module spec, explicit execution class, strict option decoding, and a
|
||
typed builder. Scene chunking, every extractor, and NPC normalization are
|
||
registered as `llm_backed`; the remaining current D&D mergers and normalizers
|
||
are `deterministic`. The metadata is available to catalog inspection and
|
||
resolved-pipeline debug data and determines which selected bindings inherit the
|
||
pipeline profile. Configuration remains the canonical owner of the exact keys,
|
||
profile precedence, 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.
|
||
|
||
Every maintained D&D LLM prompt selects `dnd-extraction` as its default
|
||
profile. The D&D registrar embeds that fallback profile with the maintained
|
||
OpenRouter model, timeout, and service-tier policy. An operator may provide a
|
||
complete profile with the same ID through the configured PromptKit source; that
|
||
definition replaces the fallback rather than merging with it. The fallback
|
||
leaves reasoning and optional sampling controls unspecified. Deployment profile
|
||
selection and the maintained operator example are documented in
|
||
[Configuration](../config.md#promptkit-profiles).
|
||
|
||
All extraction prompts share this four-message rendered prefix: the system
|
||
message without cache control, the identity message without cache control, the
|
||
campaign-reference message with ephemeral cache control, and the chunk
|
||
transcript message with ephemeral cache control. This gives equivalent
|
||
extraction requests the same reusable prefix through their source material.
|
||
|
||
Extraction-evidence policy, generated NPC registries, spell catalogs, module
|
||
tasks, and instructions follow the transcript because they are not universal
|
||
across all extraction lanes. The final instructions message carries ephemeral
|
||
cache control; evidence, registry, catalog, and task messages do not. Preserve
|
||
this division when changing an extractor or its assets so prompt-cache behavior
|
||
remains stable.
|
||
|
||
The other D&D LLM prompts intentionally follow different patterns. Scene
|
||
chunking has no sibling extraction lane with which to share its full transcript,
|
||
so it renders campaign references before its task and instructions, then places
|
||
the cacheable full transcript last. NPC normalization keeps its task and
|
||
cacheable instructions before the candidate collection, followed by the
|
||
cacheable transcript windows: candidates must be available before their
|
||
supporting evidence is evaluated, and those windows are not a cross-lane
|
||
prefix. Mounted assets and their declared message order determine the prompt
|
||
fingerprint, so intentional prompt edits continue to invalidate stale
|
||
checkpoints.
|
||
|
||
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/...
|
||
~~~
|