Document D&D spell normalization behavior

This commit is contained in:
2026-07-20 21:25:02 +00:00
parent ae97adb8b0
commit 3eb68baca6
10 changed files with 257 additions and 73 deletions

View File

@@ -186,6 +186,30 @@ function.
The normalizer returns the merged domain value unchanged and is reusable for
any registered artifact type.
### `internal/modules/dnd/normalize/spells`
The typed spell normalizer resolves the optional `spell_catalog` reference into
the same immutable SRD-plus-overlay effective catalog used by spell extraction
and catalog validation. It performs no LLM calls. For each spell cast it
canonicalizes recognized names using the catalog's case, whitespace,
apostrophe, and alias rules; sorts source references by source identity and
unit boundaries; removes only exact reference duplicates; and emits bounded,
scoped warnings for each mutation or unresolved name.
After those per-cast changes, it collapses only casts with the same canonical
spell, case-folded and whitespace-normalized caster, and complete non-empty
valid source-reference set. It retains the first occurrence and its caster,
effect, narrative description, and stable order. Unknown names, empty or
invalid evidence, and adjacent or overlapping but different ranges remain
unchanged for validation.
The normalizer exposes the effective catalog digest as its independently scoped
`effective_catalog` checkpoint fingerprint and reports catalog base ID, digest,
and overlay IDs as manifest metadata. Catalog contents, reference paths, and
raw overlay bytes are not included in either surface. The normalize-stage
reference is stage-local, so an overlay-capable pipeline binds the catalog
independently for extraction and normalization.
## Output Encoder
### `internal/modules/generic/output/json`
@@ -240,7 +264,7 @@ complete framework registry set and one LLM asset registry. It invokes
`internal/modules/seriatim/register`, and `internal/modules/dnd/register` in
that order, then exposes the matching catalog for resolution. The generic and
Seriatim registrars own their production leaf registrations. The D&D registrar
owns D&D leaf registrations, the spell default-validator chain, and D&D
owns D&D leaf registrations, the typed spell default-validator chains, and D&D
prompt/schema asset collection.
Concrete implementation packages do not import generic implementation

View File

@@ -65,8 +65,8 @@ run-local construction closures. Preparation injects shared dependencies and
constructs input, chunk, validators, ordered lanes, and output before source
parsing. Production modules use strict construction-time option decoding, and
LLM-backed modules retain the injected shared client. The D&D family registers
the canonical `dnd/spell-list` codec, typed spell extractor and validators, and
kind-specific generic merge and normalize strategies; generic JSON validators
the canonical `dnd/spell-list` codec, typed spell extractor, normalizer, and
validators, plus kind-specific generic merge strategies; generic JSON validators
use the serialized-validation contract. The runner executes lanes through
private exact-type-checked closures, coordinates extract results independently
of completion timing, and serializes artifacts only through their codec at
@@ -90,6 +90,7 @@ Configuration. The implemented module packages are:
| `internal/modules/dnd/spells/catalog` | Embeds and validates the versioned D&D 5e 2014 SRD catalog, composes optional overlays, and provides immutable effective lookup. |
| `internal/modules/generic/merge/appendorder` | Combines accepted extraction results in chunk order. |
| `internal/modules/generic/normalize/noop` | Preserves accepted merged output. |
| `internal/modules/dnd/normalize/spells` | Canonicalizes catalog-backed spell names and exact source references, conservatively collapses duplicate casts, and reports deterministic warnings and independently scoped catalog checkpoint identity. |
| `internal/modules/generic/output/json` | Encodes manifests, lane payloads, warnings, and rejections as logical JSON files. |
`internal/modules/dnd/shared` owns reusable D&D prompt fragments,