7.4 KiB
D&D Combat-Turn Artifact Contract
This document defines the durable artifact, serialization, extraction, candidate-validation, normalization, and production lane boundaries for D&D combat turns.
Artifact identity
| Property | Value |
|---|---|
| Artifact kind | dnd/combat-turn-list |
| Schema ID | notarius.dnd.combat_turns |
| Schema name | notarius_dnd_combat_turns_v1 |
| Schema version | v1 |
| Media type | application/json |
The top-level JSON object contains the required combat_turns array, which
may be empty. Every object rejects unknown fields.
JSON shape
Each combat turn contains these required fields:
| Field | Shape |
|---|---|
actor |
Non-empty string. |
turn_kind |
One of turn, reaction, legendary_action, lair_action, or other. |
source_refs |
Required array with at least one source reference. |
Source references use the shared source-reference shape:
{
"source_id": "session-alpha",
"start_unit_id": 1,
"end_unit_id": 2
}
source_id must be non-empty and both unit IDs must be positive integers. The
codec does not resolve references against a source document or enforce source
range ordering; those checks belong to the later source-reference validation
boundary.
Codec behavior
The codec exposes two representations of the same typed artifact:
- Candidate encode/decode preserves invalid actor and turn-kind values, collection presence, and source references so later validators can report them. Candidate decoding still requires valid JSON, one JSON value, known fields, and compatible JSON types.
- Approved encode/decode enforces the structural rules in this contract.
The codec owns the durable JSON Schema, whose object layers all set
additionalProperties to false. Codec metadata contains only
combat_turn_count.
The maintained compact fixture is
internal/modules/dnd/codec/combatturns/testdata/dnd_combat_turns.v1.json.
Extraction boundary
The standalone extractor uses these identities:
| Property | Value |
|---|---|
| Extractor key | dnd/combat-turns |
| Capability | dnd.combat_turns |
| Prompt ID | dnd.combat_turns |
| Prompt version | v1 |
| Private response-schema key | dnd_combat_turns_llm |
| Private response-schema ID | notarius.dnd.combat_turns.llm |
| Default profile | gemini-2-flash |
It requires chunks and source.transcript, accepts no options, and makes one
structured completion for each supplied chunk. The prompt receives the
chunk-scoped transcript plus the existing players, party, and glossary
inputs, and optionally the deprecated roster reference through the shared
party mapping. The optional npcs reference is an approved normalized NPC
artifact used only for identity grounding; it never supplies combat evidence.
An external file is validated during preparation. In an ordered pipeline, the
same slot may receive the producer's canonical generated artifact at the step
handoff.
The private response envelope has the same turn fields and JSON types as the
durable shape except that source references contain only start_unit_id
and end_unit_id. It enforces required field presence, types, and
unknown-field rejection, while deterministic validators own enum membership,
non-empty values and collections, and positive-number requirements. The
extractor assigns the current source ID, removes exact duplicate ranges, and
stable-sorts turns by the earliest valid source-document position. Numeric unit
IDs are identifiers; source-document slice position determines chronology.
Semantically malformed candidate fields remain in the typed result for the
configured validation and retry boundary.
Deterministic candidate validation
The standalone validator keys are:
| Validator | Responsibility |
|---|---|
extract/dnd/combat-turns/shape |
Required list, actor, turn kind, and source references, plus supported turn-kind values. |
extract/dnd/combat-turns/source_refs |
Source identity, source-unit existence, and range order through the source document. |
extract/dnd/combat-turns/source_relatedness |
At most one advisory warning per turn when the actor is not related to cited transcript text. |
Source-reference and relatedness validators defer malformed shape to the shape validator. Relatedness also defers when any cited source range is invalid. It combines overlapping cited ranges once in document order and compares actors with the shared Unicode-aware NPC identity policy.
The production D&D registrar exposes the extractor and these validators. Its default extraction chain preserves this order: JSON syntax, combat shape, source references, private response schema, then source relatedness.
Normalization boundary
The standalone normalizer uses key dnd/combat-turns, requires merged,
provides normalized, accepts no options, and accepts only the optional
structured npcs reference. Campaign references are LLM extraction context and
are not normalizer inputs. For an external file, the NPC registry is resolved
during preparation; for a generated binding, it is resolved at the operation-
time handoff. Runtime normalization uses that immutable prepared or handed-off
view.
Normalization policy is dnd.combat_turns.normalize.v1. It display-normalizes
the actor, canonicalizes exact registry actor 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,
and complete valid evidence set. The first normalized record is retained.
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. An external registry may additionally contribute
npc_registry_digest and npc_count; generated registry identity is retained
in framework handoff provenance and dependency fingerprints. The
normalized-invariants validator is
normalize/dnd/combat-turns/invariants; it defers shape and source-reference
failures, then checks actor display normalization, canonical evidence ordering,
chronology, and duplicate identity. It rejects
with invalid_combat_turn_normalization under policy
dnd.combat_turns.validator.normalized.v1.
The production D&D registrar exposes the normalizer and normalized-invariants validator. Its default normalization chain is JSON syntax, combat shape, normalized invariants, source references, durable schema, then source relatedness. The lane uses the framework's typed append-order merger and has no merge validator chain.
Production manifest and references
The selectable lane uses extractor and normalizer key dnd/combat-turns,
appendorder for the typed merger, and the durable codec above. A bound npcs
reference contributes raw-file provenance to the run manifest. A generated
binding contributes artifact kind, schema identity, media type, canonical
digest, size, and bounded producer provenance. Consumer metadata and checkpoint
fingerprints contain no registry names, content, paths, or NPC source ranges.
The component-local registry fingerprint covers only the names projected to the
consumer, while manifest provenance retains the full artifact digest. The
normalized lane is emitted as lanes/<lane-id>.json by the JSON
output module, and warnings and rejection summaries remain in their shared
companion files.