221 lines
11 KiB
Markdown
221 lines
11 KiB
Markdown
# Minimal D&D Extraction Contracts
|
|
|
|
**Status:** Proposed
|
|
|
|
## Intent
|
|
|
|
Redesign the D&D spell, NPC, and combat-turn artifacts around the principle in
|
|
[ADR-0009](../adr/0009-minimal-evidence-grounded-extraction-artifacts.md):
|
|
each extractor should answer one narrow question with the smallest useful set
|
|
of source-grounded fields.
|
|
|
|
The redesign favors extraction precision, evidence quality, valid-output rate,
|
|
smaller-model reliability, and lower prompt and response cost over descriptive
|
|
richness. It removes synthesis responsibilities rather than preserving obsolete
|
|
fields as optional, nullable, empty, or application-generated placeholders.
|
|
|
|
## Goals
|
|
|
|
- Make every model-produced field necessary to the artifact's core question.
|
|
- Require direct transcript evidence for every extracted record.
|
|
- Remove overlapping prose, inferred enrichment, and nested structures without
|
|
a demonstrated consumer.
|
|
- Keep catalog and identity references as disambiguation aids rather than
|
|
evidence.
|
|
- Preserve deterministic canonicalization, evidence ordering, exact
|
|
deduplication, identity assignment, and bounded domain diagnostics where
|
|
those responsibilities still apply.
|
|
- Reduce downstream prompt material to the fields a consumer actually needs.
|
|
- Keep the unpublished v1 identities while replacing their pre-release shapes
|
|
in place.
|
|
|
|
## Non-Goals
|
|
|
|
- Generating session narrative, rules analysis, biographies, relationship
|
|
graphs, encounter summaries, or prose descriptions.
|
|
- Preserving removed fields for source compatibility through empty strings,
|
|
nullable values, or synthetic defaults.
|
|
- Adding fuzzy entity resolution, LLM-assisted enrichment, or a general schema
|
|
migration framework.
|
|
- Treating campaign references, catalogs, or earlier artifacts as evidence that
|
|
an event occurred in the current transcript.
|
|
- Combining the three D&D artifact families into one model call.
|
|
|
|
## Shared Contract Policy
|
|
|
|
All three artifacts remain ordered lists. Each record contains at least one
|
|
source reference, and the complete reference collection supports every
|
|
model-produced field in that record. Source IDs continue to be assigned by the
|
|
application from the current input; the model returns only source-unit ranges.
|
|
|
|
Private LLM schemas remain strict about their transport envelope: required
|
|
fields, JSON types, object and array shape, nullability where applicable, and
|
|
unknown-field rejection. Deterministic validators continue to own semantic
|
|
rules such as nonblank identities, catalog membership, enum membership,
|
|
positive and resolvable source units, and canonical normalized invariants.
|
|
|
|
Prompts retain the shared D&D evidence, identity, reference, NPC-grounding, and
|
|
transcript assets that remain relevant. Module-specific task and instruction
|
|
assets must delete duties associated with removed fields. The existing
|
|
cache-friendly ordering keeps stable shared and reference material before the
|
|
chunk-variable transcript.
|
|
|
|
## Spell Cast
|
|
|
|
The spell extractor answers:
|
|
|
|
> Which spell was cast, by which in-world caster, and where is that event
|
|
> established in the source?
|
|
|
|
The artifact kind remains `dnd/spell-list`. Its durable schema remains v1.
|
|
Each spell-cast record contains exactly:
|
|
|
|
- `caster`: required nonblank in-world display identity;
|
|
- `spell`: required nonblank canonical or catalog-resolvable spell name; and
|
|
- `source_refs`: one or more current-source evidence ranges.
|
|
|
|
The model-facing response contains the same fields except for application-owned
|
|
`source_id` values within references. The current `effect` and
|
|
`narrative_description` fields are removed from the private response, public Go
|
|
type, durable schema, codec, validators, normalizer, fixtures, and integration
|
|
contract.
|
|
|
|
The inclusion boundary remains an actual casting event or an unambiguously
|
|
declared casting attempt, not a spell mention, hypothetical plan, rules
|
|
discussion, or catalog match. The spell catalog helps recognize and canonicalize
|
|
the name but never establishes that a cast occurred.
|
|
|
|
Normalization continues to canonicalize spell names, canonicalize evidence,
|
|
and collapse exact duplicate events using caster, canonical spell name, and
|
|
complete valid evidence. It performs no prose selection or merging.
|
|
|
|
## NPC Registry
|
|
|
|
The NPC extractor answers:
|
|
|
|
> Which individually identifiable non-player characters are established in the
|
|
> source, and where is each identity established?
|
|
|
|
The artifact kind remains `dnd/npc-list`. Its durable schema remains v1.
|
|
Each durable NPC record contains exactly:
|
|
|
|
- `id`: deterministic application-assigned identity derived under the NPC
|
|
identity policy;
|
|
- `name`: required nonblank source-supported display identity; and
|
|
- `source_refs`: one or more evidence ranges supporting that identity.
|
|
|
|
The private model response omits `id` and reference `source_id` values. A
|
|
`name` may be a proper name or a stable, individually distinguishing title or
|
|
alias supported by the transcript. The extractor does not invent descriptive
|
|
labels for anonymous creatures, crowds, or generic roles.
|
|
|
|
The current `aliases`, `description`, and `relationships` fields are removed
|
|
from the private response, public Go type, durable schema, codec, validators,
|
|
normalizer, registry, fixtures, and integration contract. Normalization
|
|
consolidates only identities supported by the retained name policy and unions
|
|
exact evidence; it does not infer alias equivalence or relationships.
|
|
|
|
Spell and combat consumers receive a prompt projection containing only the
|
|
canonical NPC names needed for identity grounding. Application-owned NPC IDs
|
|
remain available to deterministic registry and normalization code but are not
|
|
sent to a model that cannot return or otherwise consume them. NPC source
|
|
references remain provenance in the durable registry and are not included as
|
|
current-transcript evidence or copied into downstream event artifacts.
|
|
|
|
Encounter context is deliberately not a scalar NPC registry field. Dialogue,
|
|
combat alignment, presence, or third-party mention can vary across occurrences.
|
|
If a demonstrated consumer needs that information, add a separate ordered
|
|
NPC-occurrence artifact whose records contain `name`, a small mutually
|
|
exclusive context enum, and `source_refs`. A candidate starting vocabulary is
|
|
`dialogue`, `combat_ally`, `combat_opponent`, `noncombat_presence`, `mentioned`,
|
|
and `other`; its exact semantics require a separate feature decision.
|
|
|
|
## Combat Event
|
|
|
|
The combat extractor answers:
|
|
|
|
> Which in-world participant took a turn or discrete interrupting combat
|
|
> event, what kind of event was it, and where is it established in the source?
|
|
|
|
The existing `dnd/combat-turn-list` artifact kind and v1 durable-schema identity
|
|
remain. Each record contains exactly:
|
|
|
|
- `actor`: required nonblank in-world display identity;
|
|
- `turn_kind`: one of `turn`, `reaction`, `legendary_action`, `lair_action`, or
|
|
`other`; and
|
|
- `source_refs`: one or more current-source evidence ranges.
|
|
|
|
The current `round`, `actions`, and `summary` fields, including nested action
|
|
categories, declarations, targets, and resolutions, are removed from the
|
|
private response, public Go types, durable schema, codec, validators,
|
|
normalizer, fixtures, and integration contract.
|
|
|
|
Normalization continues to display-normalize and registry-canonicalize actors,
|
|
canonicalize evidence, order events by source position, and collapse exact
|
|
duplicates using actor, turn kind, and complete valid evidence. It no longer
|
|
normalizes targets, declarations, summaries, or resolutions.
|
|
|
|
If action-level facts later have a demonstrated consumer, they belong in a
|
|
separate combat-action artifact rather than restoring a nested synthesis
|
|
contract to combat-turn detection. Spell casts and future item events remain
|
|
owned by their dedicated artifact lanes.
|
|
|
|
## Pre-Release Schema Policy
|
|
|
|
Notarius and these contracts are pre-release. The existing v1 artifacts and
|
|
private model-response schemas have not been published as compatibility
|
|
contracts, so their shapes change in place. The implementation does not retain
|
|
the rich pre-redesign shape, add v2 assets, migrate old output, support multiple
|
|
versions, or preserve old fixtures solely for compatibility testing.
|
|
|
|
Artifact kinds, schema keys and IDs, schema names and versions, prompt IDs and
|
|
versions, module keys, capabilities, and media types all remain unchanged.
|
|
Changing prompt and schema content invalidates the relevant content-addressed
|
|
development state; any remaining pre-redesign local output or cache is
|
|
disposable and may be regenerated.
|
|
|
|
| Lane | Durable v1 schema | Private model-response v1 schema | Prompt ID |
|
|
| --- | --- | --- | --- |
|
|
| Spell cast | ID `notarius.dnd.spells`, name `notarius_dnd_spells_v1` | key `dnd_spells`, ID `notarius.dnd.spells`, name `notarius_dnd_spells_v1` | `dnd.spells` |
|
|
| NPC registry | ID `notarius.dnd.npcs`, name `notarius_dnd_npcs_v1` | key `dnd_npcs_llm`, ID `notarius.dnd.npcs.llm`, name `notarius_dnd_npcs_llm_v1` | `dnd.npcs` |
|
|
| Combat event | ID `notarius.dnd.combat_turns`, name `notarius_dnd_combat_turns_v1` | key `dnd_combat_turns_llm`, ID `notarius.dnd.combat_turns.llm`, name `notarius_dnd_combat_turns_llm_v1` | `dnd.combat_turns` |
|
|
|
|
## Quality And Evaluation
|
|
|
|
The implemented contract should protect the remaining meaningful risks:
|
|
|
|
- private schemas accept only the new structural envelopes;
|
|
- durable codecs strictly round-trip the redesigned contracts;
|
|
- domain validators own blank identities, enum and catalog membership, and
|
|
invalid evidence;
|
|
- normalizers preserve source-grounded values while applying only their stated
|
|
deterministic transformations;
|
|
- generated NPC references expose the minimal identity projection and never
|
|
become event evidence; and
|
|
- representative assembled pipelines attribute retries and rejections to the
|
|
owning domain boundary.
|
|
|
|
Post-cutover model evaluation should compare the rich-schema baseline and the
|
|
minimal-schema result on a small human-reviewed transcript set using:
|
|
|
|
- event/entity precision and recall;
|
|
- caster, NPC, and combat-actor attribution accuracy;
|
|
- source-range validity and evidence sufficiency;
|
|
- catalog and enum accuracy;
|
|
- structurally valid completion rate and exhausted-retry rate;
|
|
- unsupported-claim rate; and
|
|
- input/output tokens, latency, and model cost.
|
|
|
|
The evaluation exists to identify prompt or model-quality follow-up work, not
|
|
to gate the approved minimal contract on live-provider behavior. Human review
|
|
and live model calls are evaluation aids rather than deterministic CI gates.
|
|
|
|
## Documentation Ownership
|
|
|
|
The spell, NPC, and combat integration documents are the canonical owners of
|
|
their redesigned durable schemas once implemented. Internal LLM and module
|
|
documents own the corresponding current prompt, DTO, validator, normalizer, and
|
|
NPC prompt-projection behavior. This roadmap owns the desired end state and
|
|
policy; [the implementation plan](implementation.md) owns sequencing and
|
|
completion criteria until the cutover is complete.
|