Compose production D&D combat pipeline

This commit is contained in:
2026-07-21 05:42:33 +00:00
parent 50aa60e0b8
commit a1f5dce405
19 changed files with 963 additions and 62 deletions

View File

@@ -23,6 +23,8 @@ The explicit-path option is defined in the [CLI reference](cli.md).
- [Production-oriented D&D spell configuration](../examples/dnd-spells-production.config.yml)
- [D&D NPC configuration](../examples/dnd-npcs.config.yml)
- [Sequential D&D NPC and spell configuration](../examples/dnd-npc-spell-sequential.config.yml)
- [D&D combat-turn configuration](../examples/dnd-combat-turns.config.yml)
- [Sequential D&D NPC and combat-turn configuration](../examples/dnd-npc-combat-sequential.config.yml)
All are complete version 3 files. The fragments below illustrate individual
fields and are not alternate complete configurations.
@@ -286,10 +288,12 @@ production validators do not call the LLM and must not set `llm_profile`.
| chunk | `dnd/scenes` | Uses an LLM to split transcript source units into D&D scenes. |
| extract | `dnd/spells` | Extracts typed D&D spell-list artifacts. |
| extract | `dnd/npcs` | Extracts typed D&D NPC-list artifacts. |
| extract | `dnd/combat-turns` | Extracts typed D&D combat-turn-list artifacts. |
| merge | `appendorder` | Combines typed artifacts in chunk order. |
| normalize | `noop` | Passes merged typed artifacts through unchanged. |
| normalize | `dnd/spells` | Deterministically canonicalizes and de-duplicates typed D&D spell-list artifacts. |
| normalize | `dnd/npcs` | Deterministically consolidates typed D&D NPC-list artifacts by canonical identity and aliases. |
| normalize | `dnd/combat-turns` | Deterministically canonicalizes, orders, and de-duplicates typed D&D combat-turn artifacts. |
| output | `json` | Produces JSON output files for normalized `application/json` lanes. |
## Implemented Production Validators
@@ -308,6 +312,10 @@ production validators do not call the LLM and must not set `llm_profile`.
| `extract/dnd/npcs/source_refs` | deterministic | Rejects missing or invalid D&D NPC source references. |
| `extract/dnd/npcs/source_relatedness` | deterministic | Emits warnings when an NPC name or alias is not found near its cited source text. |
| `normalize/dnd/npcs/identity` | deterministic | Rejects invalid canonical IDs, aliases, and cross-record identity collisions. |
| `extract/dnd/combat-turns/shape` | deterministic | Rejects malformed D&D combat-turn artifacts. |
| `extract/dnd/combat-turns/source_refs` | deterministic | Rejects missing or invalid D&D combat-turn source references. |
| `extract/dnd/combat-turns/source_relatedness` | deterministic | Emits warnings when an actor or declared action is not found near cited source text. |
| `normalize/dnd/combat-turns/invariants` | deterministic | Rejects normalized combat-turn identity, target, evidence-order, and chronology violations. |
The production default chain for `dnd/spells` is used for both its extract and
normalize stages:
@@ -342,6 +350,26 @@ normalize:
- extract/dnd/npcs/source_relatedness
```
The production default chains for `dnd/combat-turns` are:
```yaml
extract:
validators:
- generic/valid_json
- generic/valid_json_schema
- extract/dnd/combat-turns/shape
- extract/dnd/combat-turns/source_refs
- extract/dnd/combat-turns/source_relatedness
normalize:
validators:
- generic/valid_json
- generic/valid_json_schema
- extract/dnd/combat-turns/shape
- normalize/dnd/combat-turns/invariants
- extract/dnd/combat-turns/source_refs
- extract/dnd/combat-turns/source_relatedness
```
Empty chains approve output by default.
The `generic` chunker accepts:
@@ -395,6 +423,26 @@ accepts no references. To pass an NPC result to a later spell run, bind the
normalized payload explicitly at runtime; the maintained sequential example
documents that operator workflow.
The `dnd/combat-turns` extractor and normalizer declare the same optional
campaign slots and the structured `npcs` slot. The combat extractor uses the
NPC payload only to ground actor and target identity; the normalizer uses its
prepared immutable registry for the same canonicalization. Both slots accept
exactly one UTF-8 `application/json` file no larger than 1 MiB. The registry's
source ranges remain provenance for the reference and never become combat
evidence. Binding `npcs` to extraction and normalization is stage-local, so an
operator-driven combat run uses two explicit selectors:
```text
combat.extract.npcs=<npc-run>/lanes/npcs.json
combat.normalize.npcs=<npc-run>/lanes/npcs.json
```
When bound, the combat extractor and normalizer record only the registry's
semantic digest and count in their metadata and checkpoint fingerprints; names,
aliases, content, and paths are not recorded there. When absent, the combat
prompt receives the exact empty registry value `{"npcs":[]}` and no registry
provenance or fingerprint is recorded.
## State Surfaces
The `output`, `cache`, and `debug` top-level fields select independent physical