Add combat turn normalization and invariants

This commit is contained in:
2026-07-21 05:22:12 +00:00
parent 2fbb3813aa
commit 50aa60e0b8
7 changed files with 1273 additions and 9 deletions

View File

@@ -1,8 +1,9 @@
# D&D Combat-Turn Artifact Contract
This document defines the durable artifact, serialization, extraction, and
candidate-validation boundaries for D&D combat turns. Normalization and a
selectable production pipeline lane are not part of this contract yet.
This document defines the durable artifact, serialization, extraction,
candidate-validation, and standalone normalization boundaries for D&D combat
turns. Production composition and a selectable pipeline lane are not part of
this contract yet.
## Artifact identity
@@ -119,5 +120,34 @@ at least four Unicode code points against complete cited-text tokens. Targets
are not checked deterministically.
The extractor and validators are package-complete but are not registered by the
production D&D family registrar yet. Normalization, production composition,
and selectable configuration are defined when implemented.
production D&D family registrar yet.
## Normalization boundary
The standalone normalizer uses key `dnd/combat-turns`, requires `merged`,
provides `normalized`, accepts no options, and accepts the same optional
`players`, `party`, `glossary`, deprecated `roster`, and structured `npcs`
reference slots as extraction. The NPC registry is resolved during
preparation; runtime normalization uses that immutable prepared view.
Normalization policy is `dnd.combat_turns.normalize.v1`. It display-normalizes
actor, summary, declarations, targets, and non-null resolutions; canonicalizes
exact registry actor and target matches; orders and deduplicates exact source
references; stable-sorts records by earliest valid source-document position; and
collapses only records with the same actor identity, turn kind, round value, and
complete valid evidence set. The first normalized record is retained without
merging its actions or prose. Invalid evidence is never eligible for duplicate
collapse. Every mutation and collapse emits a bounded warning using the merged
input index in its scope.
The normalizer reports `normalization_policy` and `identity_policy` metadata and
fingerprints, plus `npc_registry_digest`, `npc_count`, and `npc_registry` only
when a registry is bound. The normalized-invariants validator is
`normalize/dnd/combat-turns/invariants`; it defers shape and source-reference
failures, then checks display normalization, target identity uniqueness,
canonical evidence ordering, chronology, and duplicate identity. It rejects
with `invalid_combat_turn_normalization` under policy
`dnd.combat_turns.validator.normalized.v1`.
The normalizer and normalized-invariants validator are package-complete but are
not registered by the production D&D family registrar yet.

View File

@@ -284,6 +284,19 @@ 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.
### `internal/modules/dnd/normalize/combatturns`
The combat normalizer prepares the optional NPC registry once and uses the
immutable prepared view during runtime. It display-normalizes combat fields,
rewrites exact canonical-name or alias matches for actors and targets, orders
and deduplicates source references, stable-sorts records by source-document
position, and collapses only exact duplicate identities with fully valid
evidence. It deep-clones output storage and emits bounded warnings scoped to
merged input indexes. Its metadata and fingerprints identify the normalization
and NPC identity policies, with registry digest/count only when bound. The
normalizer is package-complete but is not registered in the production D&D
registrar.
## Output Encoder
### `internal/modules/generic/output/json`
@@ -348,9 +361,12 @@ rounds, and supported enums. Combat source-reference validation defers invalid
shape and checks source identity, unit existence, and range order. Combat
source-relatedness defers invalid shape or ranges, combines overlapping cited
units in document order, and emits at most one bounded advisory warning per
turn for unrelated actor or declaration text. All three validators are
deterministic and expose local policy fingerprints; they are package-complete
but not yet in a production validator chain.
turn for unrelated actor or declaration text. The normalized-invariants
validator owns display normalization, comparison-unique targets, canonical
source-reference order, chronology, and exact duplicate identity; it defers
shape and source-reference failures. All four validators are deterministic and
expose local policy fingerprints; they are package-complete but not yet in a
production validator chain.
## Production Registration

View File

@@ -91,7 +91,8 @@ Configuration. The implemented module packages are:
| `internal/modules/dnd/extract/spells` | Maps private structured model output to canonical source-grounded D&D spell lists. |
| `internal/modules/dnd/extract/npcs` | Maps private structured model output to canonical source-grounded D&D NPC lists. |
| `internal/modules/dnd/extract/combatturns` | Maps private structured model output to source-grounded D&D combat-turn candidates and preserves chronology and invalid candidate values for validators. |
| `internal/modules/dnd/validate/combatturns` | Provides deterministic shape, source-reference, and source-relatedness validation for combat-turn candidates without production composition. |
| `internal/modules/dnd/normalize/combatturns` | Canonicalizes and orders merged combat turns, applies exact NPC identity matches, and collapses only exact valid-evidence duplicates without production composition. |
| `internal/modules/dnd/validate/combatturns` | Provides deterministic shape, source-reference, source-relatedness, and normalized-invariant validation for combat turns without production composition. |
| `internal/modules/dnd/npcs/registry` | Resolves validated normalized NPC references into immutable grounding data and exact identity lookup. |
| `internal/modules/dnd/npcs/identity` | Owns Unicode-aware NPC identity, ID derivation, and registry collision validation. |
| `internal/modules/dnd/spells/catalog` | Embeds and validates the versioned D&D 5e 2014 SRD catalog, composes optional overlays, and provides immutable effective lookup. |