148 lines
6.3 KiB
Markdown
148 lines
6.3 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 in-world caster, not
|
|
the transcript speaker. 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.
|
|
|
|
## 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.
|
|
|
|
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`.
|
|
|
|
## 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"]
|
|
},
|
|
"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).
|