205 lines
9.8 KiB
Markdown
205 lines
9.8 KiB
Markdown
# D&D Spell Artifact
|
|
|
|
This document is the durable serialized artifact contract for the production
|
|
D&D spell extractor. Selectable extractor keys are cataloged in
|
|
[Configuration](../config.md#implemented-production-modules).
|
|
|
|
## Identity
|
|
|
|
- Artifact kind: `dnd/spell-list`
|
|
- Prompt ID: `dnd.spells`
|
|
- Response schema key: `dnd_spells`
|
|
- Response schema ID: `notarius.dnd.spells`
|
|
- Response schema name: `notarius_dnd_spells_v1`
|
|
- Response schema version: `v1`
|
|
- Media type: `application/json`
|
|
|
|
The durable JSON Schema is owned by the D&D spell artifact codec. The
|
|
extractor's private LLM response schema is a separate transport contract: its
|
|
source-reference objects omit `source_id`, which the extractor assigns while
|
|
mapping the response to the canonical artifact. The LLM DTO and transport
|
|
schema are not part of this durable contract.
|
|
|
|
The output contains canonical spell casts derived from transcript evidence.
|
|
Source IDs are assigned from the input identity; source-unit ranges identify
|
|
the evidence location.
|
|
|
|
## Output Shape
|
|
|
|
The extractor payload is a JSON object with one required top-level array. Its
|
|
structure is:
|
|
|
|
```text
|
|
{"spell_casts": [<spell-cast object>, ...]}
|
|
```
|
|
|
|
`spell_casts` must be present. It may be empty when no spell casts are found.
|
|
When multiple chunk results are combined, spell casts remain in chunk order.
|
|
When the payload is written as durable output, its logical path is derived from
|
|
the configured artifact lane ID as defined by the
|
|
[JSON output contract](json-output.md#output-payload-files).
|
|
|
|
## Spell-Cast Fields
|
|
|
|
Each spell cast contains exactly these required fields:
|
|
|
|
- `caster`: in-world character or creature casting the spell;
|
|
- `spell`: spell name;
|
|
- `effect`: concise spell effect in the scene;
|
|
- `narrative_description`: short description of the spell cast in context;
|
|
- `source_refs`: transcript source references with extractor-assigned source
|
|
IDs and evidence unit ranges. It must contain at least one entry.
|
|
|
|
All four string fields must be non-empty. `caster` is the canonical in-world
|
|
caster, not the human player, transcript speaker, or GM when the associated
|
|
character or creature can be identified. Player and party references may
|
|
disambiguate that identity, but do not independently establish that a cast
|
|
occurred. The `spell` value must resolve through the effective SRD-plus-overlay
|
|
catalog as either a canonical name or alias. Catalog validation accepts aliases
|
|
but does not rewrite them; unknown fields are rejected.
|
|
|
|
`effect` and `narrative_description` record the casting declaration and its
|
|
immediate resolution as established by the transcript. They do not follow
|
|
summoned creatures, persistent spell effects, or other downstream consequences
|
|
through the rest of the scene. They also do not correct the table from
|
|
published D&D rules or supplement the transcript with model knowledge. When the
|
|
transcript contains a nonstandard or disputed ruling, the artifact may preserve
|
|
the immediate observed resolution and attribute relevant reasoning to the GM or
|
|
table; it must not present that reasoning as a universal game rule. The spell
|
|
catalog is name-recognition policy, not evidence for spell mechanics or
|
|
outcomes.
|
|
|
|
## Source References
|
|
|
|
Each source reference contains exactly three required fields: `source_id`,
|
|
`start_unit_id`, and `end_unit_id`. The source ID must match the input identity.
|
|
The unit IDs must be positive integers present in the input, and the start unit
|
|
must not appear after the end unit. Unknown fields are rejected.
|
|
|
|
For each cast, the complete `source_refs` collection identifies the transcript
|
|
evidence for every factual claim in `caster`, `spell`, `effect`, and
|
|
`narrative_description`. A cast declaration and its immediate resolution may be
|
|
cited with separate narrow ranges when intervening units are unrelated. A
|
|
reported target, roll, amount, condition, interruption, or immediate outcome
|
|
must be supported by the cited units; otherwise the artifact describes only the
|
|
supported attempt or declaration. Later behavior by summoned creatures,
|
|
recurring effects, and other downstream consequences are outside the cast
|
|
artifact's evidence scope. The deterministic validators establish that ranges
|
|
are structurally valid and that the spell name is related to cited text.
|
|
Semantic claim completeness is an extraction policy and remains subject to
|
|
evaluation rather than deterministic proof.
|
|
|
|
Reference slot keys and accepted file types are defined in
|
|
[Configuration](../config.md#implemented-production-modules). References are
|
|
supporting disambiguation material, not source evidence, and are not
|
|
addressable through `source_refs`.
|
|
|
|
## Optional NPC Grounding
|
|
|
|
The `dnd/spells` extractor accepts an optional `npcs` reference containing one
|
|
normalized NPC artifact as `application/json`, up to 1 MiB. Preparation uses
|
|
the approved NPC codec and identity policy to validate the file, re-encodes
|
|
canonical durable JSON, and supplies that JSON as a spell-owned prompt input.
|
|
It helps the model prefer canonical caster names and recognize aliases; it
|
|
does not establish that a spell was cast.
|
|
|
|
NPC source references may identify the run that produced the registry or any
|
|
other session. They remain registry provenance and are never copied into a
|
|
spell cast's `source_refs`; every spell evidence range must still identify the
|
|
current transcript. When the slot is absent, the prompt receives exactly
|
|
`{"npcs":[]}` and the run has no NPC reference provenance or NPC checkpoint
|
|
fingerprint.
|
|
|
|
## Normalization Behavior
|
|
|
|
When the `dnd/spells` normalizer is selected, each recognized spell name is
|
|
rewritten to the effective catalog's canonical display name. Lookup uses the
|
|
catalog's case-insensitive, whitespace-normalizing, apostrophe-normalizing, and
|
|
alias rules. Unknown names are preserved exactly for the normalize validators;
|
|
the normalizer does not guess or apply fuzzy matching.
|
|
|
|
Each cast's `source_refs` is copied, sorted by exact `source_id`,
|
|
`start_unit_id`, and `end_unit_id`, and stripped of exact structural
|
|
duplicates. Adjacent or overlapping ranges are not merged, and the normalizer
|
|
does not synthesize references or change their boundaries.
|
|
|
|
After those per-cast changes, duplicate identity requires the same canonical
|
|
spell name, the same caster after case folding and whitespace normalization,
|
|
and the same complete, non-empty set of source references valid for the source
|
|
document. Only the first occurrence is retained, in stable order. Its caster,
|
|
effect, narrative description, and canonical references are preserved without
|
|
prose merging or source union. Unknown names, empty or invalid evidence, and
|
|
casts with different evidence remain separate.
|
|
|
|
Mutation and duplicate decisions are returned through the normal warnings
|
|
surface. Warning scopes use the merged input index, such as `spell_casts[0]`,
|
|
so they remain meaningful even when a later duplicate is removed. The
|
|
normalizer uses these reason codes:
|
|
|
|
| Reason code | Meaning |
|
|
| --- | --- |
|
|
| `spell_name_canonicalized` | A catalog lookup replaced an input name with its canonical display name. |
|
|
| `spell_name_unresolved` | A name was not found in the effective catalog and was retained unchanged. |
|
|
| `source_references_normalized` | Reference order changed or exact duplicate references were removed. |
|
|
| `duplicate_spell_cast_collapsed` | A later cast matched the retained cast's complete duplicate identity. |
|
|
|
|
Only warnings from an accepted normalize attempt are promoted to
|
|
`warnings.json`. If an unresolved name reaches the default normalize validator
|
|
chain, the catalog validator rejects the candidate with `unknown_spell`; the
|
|
`spell_name_unresolved` warning remains in the attempt's debug artifact. An
|
|
explicit validator override that accepts the candidate promotes the unresolved
|
|
warning normally.
|
|
|
|
## Manifest Metadata
|
|
|
|
The extractor adds prompt and response-schema provenance under the artifact lane
|
|
manifest metadata:
|
|
|
|
```json
|
|
{
|
|
"metadata": {
|
|
"extractor": {
|
|
"prompt_id": "dnd.spells",
|
|
"prompt_version": "v1",
|
|
"prompt_sha256": "sha256:...",
|
|
"response_schema_key": "dnd_spells",
|
|
"response_schema_id": "notarius.dnd.spells",
|
|
"response_schema_name": "notarius_dnd_spells_v1",
|
|
"response_schema_version": "v1",
|
|
"response_schema_sha256": "sha256:...",
|
|
"catalog_base_id": "dnd-5e-2014-srd-spells",
|
|
"catalog_digest": "sha256:...",
|
|
"catalog_overlay_ids": ["campaign.example"],
|
|
"npc_registry_digest": "sha256:...",
|
|
"npc_count": 3
|
|
},
|
|
"normalizer": {
|
|
"catalog_base_id": "dnd-5e-2014-srd-spells",
|
|
"catalog_digest": "sha256:...",
|
|
"catalog_overlay_ids": ["campaign.example"]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
`catalog_digest` identifies the effective semantic catalog, while
|
|
`catalog_overlay_ids` is sorted and empty for a base-only configuration. Raw
|
|
prompt, schema, catalog, alias, and local overlay-file content are not
|
|
included in manifest metadata. The `normalizer` metadata uses the same catalog
|
|
identity fields when that module is selected. Overlay origin, media type, byte
|
|
size, and raw digest are recorded separately in the manifest's reference
|
|
provenance; see the [JSON output contract](json-output.md#manifestjson).
|
|
|
|
The `npc_registry_digest` and `npc_count` fields in the example are present only
|
|
when the optional NPC registry is bound. They contain no NPC names, aliases,
|
|
source references, paths, or raw bytes.
|
|
|
|
The extractor's prompt hash, private response-schema hash, and effective catalog
|
|
digest also contribute independently scoped semantic checkpoint fingerprints.
|
|
Changing any of those prepared contracts intentionally produces a cold
|
|
checkpoint miss. Fingerprints contain only digests, never prompt, schema,
|
|
catalog, or reference content. When an NPC registry is bound, its semantic
|
|
digest contributes an additional local `npc_registry` fingerprint; the
|
|
manifest metadata contains only that digest and `npc_count`. Raw NPC file
|
|
provenance remains independently recorded in the manifest's `references` list.
|