Verify complete D&D entity handoffs

This commit is contained in:
2026-08-05 20:07:31 +00:00
parent a6e176e160
commit 6de470d541
5 changed files with 260 additions and 36 deletions

View File

@@ -30,16 +30,32 @@ import (
combatcodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/combatturns"
enemyeventcodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/enemyevents"
itemoccurrencecodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/itemoccurrences"
itemregistrycodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/itemregistry"
locationoccurrencecodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/locationoccurrences"
locationcodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/locationregistry"
npcoccurrencecodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcoccurrences"
npccodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/npcregistry"
scenecodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/scenedescriptions"
spellcodec "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/codec/spells"
combatextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/combatturns"
enemyeventextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/enemyevents"
itemoccurrenceextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/itemoccurrences"
itemregistryextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/itemregistry"
locationoccurrenceextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/locationoccurrences"
locationextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/locationregistry"
npcoccurrenceextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcoccurrences"
npcextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/npcregistry"
sceneextract "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/scenedescriptions"
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/extract/spells"
combatnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/combatturns"
enemyeventnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/enemyevents"
itemoccurrencenormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/itemoccurrences"
itemregistrynormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/itemregistry"
locationoccurrencenormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/locationoccurrences"
locationnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/locationregistry"
npcoccurrencenormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcoccurrences"
npcnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/npcregistry"
scenenormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/scenedescriptions"
spellnormalize "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/normalize/spells"
"gitea.maximumdirect.net/eric/notarius/internal/modules/generic/normalize/noop"
"gitea.maximumdirect.net/eric/promptkit"
@@ -51,9 +67,9 @@ func TestProductionCatalogCoversMaintainedConfigurations(t *testing.T) {
assertProductionContains(t, "inputs", registries.Inputs.RegisteredKeys(), []string{"seriatim"})
assertProductionContains(t, "chunkers", registries.Chunkers.RegisteredKeys(), []string{"dnd/scenes", "generic"})
assertProductionContains(t, "extractors", registries.Extractors.RegisteredKeys(), []string{"dnd/spells", "dnd/npc-registry", combatextract.Key, itemoccurrenceextract.Key, enemyeventextract.Key})
assertProductionContains(t, "extractors", registries.Extractors.RegisteredKeys(), []string{spells.Key, npcextract.Key, combatextract.Key, itemoccurrenceextract.Key, itemregistryextract.Key, npcoccurrenceextract.Key, sceneextract.Key, locationextract.Key, locationoccurrenceextract.Key, enemyeventextract.Key})
assertProductionContains(t, "mergers", registries.Mergers.RegisteredKeys(), []string{"appendorder"})
assertProductionContains(t, "normalizers", registries.Normalizers.RegisteredKeys(), []string{"noop", spellnormalize.Key, "dnd/npc-registry", combatnormalize.Key, itemoccurrencenormalize.Key, enemyeventnormalize.Key})
assertProductionContains(t, "normalizers", registries.Normalizers.RegisteredKeys(), []string{pipeline.DefaultNormalizeModule, spellnormalize.Key, npcnormalize.Key, combatnormalize.Key, itemoccurrencenormalize.Key, itemregistrynormalize.Key, npcoccurrencenormalize.Key, scenenormalize.Key, locationnormalize.Key, locationoccurrencenormalize.Key, enemyeventnormalize.Key})
assertProductionContains(t, "outputs", registries.Outputs.RegisteredKeys(), []string{"json"})
assertProductionContains(t, "validators", registries.Validators.RegisteredKeys(), []string{
"extract/dnd/spells/catalog",
@@ -65,9 +81,36 @@ func TestProductionCatalogCoversMaintainedConfigurations(t *testing.T) {
"extract/dnd/combat-turns/source_relatedness",
"normalize/dnd/combat-turns/invariants",
"extract/dnd/item-occurrences/shape",
"extract/dnd/item-occurrences/registry",
"extract/dnd/item-occurrences/source_refs",
"extract/dnd/item-occurrences/source_relatedness",
"normalize/dnd/item-occurrences/invariants",
"extract/dnd/item-registry/shape",
"extract/dnd/item-registry/source_refs",
"extract/dnd/item-registry/source_relatedness",
"normalize/dnd/item-registry/identity",
"extract/dnd/npc-registry/shape",
"extract/dnd/npc-registry/source_refs",
"extract/dnd/npc-registry/source_relatedness",
"normalize/dnd/npc-registry/identity",
"extract/dnd/npc-occurrences/shape",
"extract/dnd/npc-occurrences/registry",
"extract/dnd/npc-occurrences/source_refs",
"extract/dnd/npc-occurrences/source_relatedness",
"normalize/dnd/npc-occurrences/invariants",
"extract/dnd/scene-descriptions/shape",
"extract/dnd/scene-descriptions/source_refs",
"extract/dnd/scene-descriptions/source_relatedness",
"normalize/dnd/scene-descriptions/invariants",
"extract/dnd/location-registry/shape",
"extract/dnd/location-registry/source_refs",
"extract/dnd/location-registry/source_relatedness",
"normalize/dnd/location-registry/identity",
"extract/dnd/location-occurrences/shape",
"extract/dnd/location-occurrences/registry",
"extract/dnd/location-occurrences/source_refs",
"extract/dnd/location-occurrences/source_relatedness",
"normalize/dnd/location-occurrences/invariants",
"extract/dnd/enemy-events/shape",
"extract/dnd/enemy-events/engagements",
"extract/dnd/enemy-events/source_refs",
@@ -78,12 +121,19 @@ func TestProductionCatalogCoversMaintainedConfigurations(t *testing.T) {
"generic/valid_json",
"generic/valid_json_schema",
})
assertProductionContains(t, "artifact codec kinds", registries.ArtifactCodecs.RegisteredKinds(), []contracts.ArtifactKind{dnd.SpellListKind, dnd.NPCRegistryKind, dnd.CombatTurnListKind, dnd.ItemOccurrenceListKind, dnd.EnemyEventListKind})
assertProductionContains(t, "merger variants", registries.Mergers.RegisteredArtifactKinds(pipeline.DefaultMergeModule), []contracts.ArtifactKind{dnd.SpellListKind, dnd.NPCRegistryKind, dnd.CombatTurnListKind, dnd.ItemOccurrenceListKind, dnd.EnemyEventListKind})
assertProductionContains(t, "normalizer variants", registries.Normalizers.RegisteredArtifactKinds(pipeline.DefaultNormalizeModule), []contracts.ArtifactKind{dnd.SpellListKind, dnd.NPCRegistryKind, dnd.CombatTurnListKind, dnd.ItemOccurrenceListKind, dnd.EnemyEventListKind})
allArtifactKinds := []contracts.ArtifactKind{dnd.SpellListKind, dnd.NPCRegistryKind, dnd.NPCOccurrenceListKind, dnd.CombatTurnListKind, dnd.SceneDescriptionListKind, dnd.LocationRegistryKind, dnd.LocationOccurrenceListKind, dnd.ItemRegistryKind, dnd.ItemOccurrenceListKind, dnd.EnemyEventListKind}
assertProductionContains(t, "artifact codec kinds", registries.ArtifactCodecs.RegisteredKinds(), allArtifactKinds)
assertProductionContains(t, "merger variants", registries.Mergers.RegisteredArtifactKinds(pipeline.DefaultMergeModule), allArtifactKinds)
assertProductionContains(t, "normalizer variants", registries.Normalizers.RegisteredArtifactKinds(pipeline.DefaultNormalizeModule), allArtifactKinds)
assertProductionContains(t, "spell normalizer variants", registries.Normalizers.RegisteredArtifactKinds(spellnormalize.Key), []contracts.ArtifactKind{dnd.SpellListKind})
assertProductionContains(t, "combat normalizer variants", registries.Normalizers.RegisteredArtifactKinds(combatnormalize.Key), []contracts.ArtifactKind{dnd.CombatTurnListKind})
assertProductionContains(t, "item occurrence normalizer variants", registries.Normalizers.RegisteredArtifactKinds(itemoccurrencenormalize.Key), []contracts.ArtifactKind{dnd.ItemOccurrenceListKind})
assertProductionContains(t, "item registry normalizer variants", registries.Normalizers.RegisteredArtifactKinds(itemregistrynormalize.Key), []contracts.ArtifactKind{dnd.ItemRegistryKind})
assertProductionContains(t, "NPC registry normalizer variants", registries.Normalizers.RegisteredArtifactKinds(npcnormalize.Key), []contracts.ArtifactKind{dnd.NPCRegistryKind})
assertProductionContains(t, "NPC occurrence normalizer variants", registries.Normalizers.RegisteredArtifactKinds(npcoccurrencenormalize.Key), []contracts.ArtifactKind{dnd.NPCOccurrenceListKind})
assertProductionContains(t, "scene description normalizer variants", registries.Normalizers.RegisteredArtifactKinds(scenenormalize.Key), []contracts.ArtifactKind{dnd.SceneDescriptionListKind})
assertProductionContains(t, "location registry normalizer variants", registries.Normalizers.RegisteredArtifactKinds(locationnormalize.Key), []contracts.ArtifactKind{dnd.LocationRegistryKind})
assertProductionContains(t, "location occurrence normalizer variants", registries.Normalizers.RegisteredArtifactKinds(locationoccurrencenormalize.Key), []contracts.ArtifactKind{dnd.LocationOccurrenceListKind})
assertProductionContains(t, "enemy event normalizer variants", registries.Normalizers.RegisteredArtifactKinds(enemyeventnormalize.Key), []contracts.ArtifactKind{dnd.EnemyEventListKind})
wantChain := []pipeline.ModuleBinding{
@@ -167,18 +217,24 @@ func TestProductionCatalogCoversMaintainedConfigurations(t *testing.T) {
{stage: pipeline.StageChunk, key: "dnd/scenes", want: contracts.ExecutionClassLLMBacked},
{stage: pipeline.StageExtract, key: "dnd/spells", want: contracts.ExecutionClassLLMBacked},
{stage: pipeline.StageExtract, key: "dnd/npc-registry", want: contracts.ExecutionClassLLMBacked},
{stage: pipeline.StageExtract, key: "dnd/location-registry", want: contracts.ExecutionClassLLMBacked},
{stage: pipeline.StageExtract, key: "dnd/item-registry", want: contracts.ExecutionClassLLMBacked},
{stage: pipeline.StageExtract, key: "dnd/combat-turns", want: contracts.ExecutionClassLLMBacked},
{stage: pipeline.StageExtract, key: "dnd/item-occurrences", want: contracts.ExecutionClassLLMBacked},
{stage: pipeline.StageExtract, key: "dnd/npc-occurrences", want: contracts.ExecutionClassLLMBacked},
{stage: pipeline.StageExtract, key: "dnd/location-occurrences", want: contracts.ExecutionClassLLMBacked},
{stage: pipeline.StageExtract, key: "dnd/scene-descriptions", want: contracts.ExecutionClassLLMBacked},
{stage: pipeline.StageExtract, key: enemyeventextract.Key, want: contracts.ExecutionClassLLMBacked},
{stage: pipeline.StageMerge, key: "appendorder", want: contracts.ExecutionClassDeterministic},
{stage: pipeline.StageNormalize, key: "noop", want: contracts.ExecutionClassDeterministic},
{stage: pipeline.StageNormalize, key: "dnd/spells", want: contracts.ExecutionClassDeterministic},
{stage: pipeline.StageNormalize, key: "dnd/npc-registry", want: contracts.ExecutionClassLLMBacked},
{stage: pipeline.StageNormalize, key: "dnd/location-registry", want: contracts.ExecutionClassLLMBacked},
{stage: pipeline.StageNormalize, key: "dnd/item-registry", want: contracts.ExecutionClassLLMBacked},
{stage: pipeline.StageNormalize, key: "dnd/combat-turns", want: contracts.ExecutionClassDeterministic},
{stage: pipeline.StageNormalize, key: "dnd/item-occurrences", want: contracts.ExecutionClassDeterministic},
{stage: pipeline.StageNormalize, key: "dnd/npc-occurrences", want: contracts.ExecutionClassDeterministic},
{stage: pipeline.StageNormalize, key: "dnd/location-occurrences", want: contracts.ExecutionClassDeterministic},
{stage: pipeline.StageNormalize, key: "dnd/scene-descriptions", want: contracts.ExecutionClassDeterministic},
{stage: pipeline.StageNormalize, key: enemyeventnormalize.Key, want: contracts.ExecutionClassDeterministic},
{stage: pipeline.StageOutput, key: "json", want: contracts.ExecutionClassDeterministic},
@@ -204,6 +260,23 @@ func TestProductionCatalogCoversMaintainedConfigurations(t *testing.T) {
if !ok || itemOccurrenceCodecSpec.Kind != dnd.ItemOccurrenceListKind || itemOccurrenceCodecSpec.Schema.ID != itemoccurrencecodec.SchemaID {
t.Fatalf("item occurrence codec spec = %#v, ok=%t, want typed D&D item-occurrence codec", itemOccurrenceCodecSpec, ok)
}
for _, test := range []struct {
name string
kind contracts.ArtifactKind
id string
}{
{name: "NPC registry", kind: dnd.NPCRegistryKind, id: npccodec.SchemaID},
{name: "NPC occurrences", kind: dnd.NPCOccurrenceListKind, id: npcoccurrencecodec.SchemaID},
{name: "item registry", kind: dnd.ItemRegistryKind, id: itemregistrycodec.SchemaID},
{name: "scene descriptions", kind: dnd.SceneDescriptionListKind, id: scenecodec.SchemaID},
{name: "location registry", kind: dnd.LocationRegistryKind, id: locationcodec.SchemaID},
{name: "location occurrences", kind: dnd.LocationOccurrenceListKind, id: locationoccurrencecodec.SchemaID},
} {
spec, found := catalog.ArtifactCodecs.Spec(test.kind)
if !found || spec.Kind != test.kind || spec.Schema.ID != test.id {
t.Fatalf("%s codec spec = %#v, found=%t, want typed D&D codec", test.name, spec, found)
}
}
enemyEventCodecSpec, ok := catalog.ArtifactCodecs.Spec(dnd.EnemyEventListKind)
if !ok || enemyEventCodecSpec.Kind != dnd.EnemyEventListKind || enemyEventCodecSpec.Schema.ID != enemyeventcodec.SchemaID {
t.Fatalf("enemy event codec spec = %#v, ok=%t, want typed D&D enemy-event codec", enemyEventCodecSpec, ok)