Implement operation-time D&D NPC artifact handoff

This commit is contained in:
2026-07-21 22:12:01 +00:00
parent c437682407
commit 9184072839
12 changed files with 606 additions and 27 deletions

View File

@@ -70,6 +70,36 @@ func TestNormalizeCanonicalizesFieldsAndRegistryIdentities(t *testing.T) {
}
}
func TestNormalizeResolvesOperationNPCOverrideWithoutSingletonMetadata(t *testing.T) {
doc := testDocument()
normalizer, err := New(Options{})
if err != nil {
t.Fatalf("New() error = %v", err)
}
input := dnd.CombatTurnList{CombatTurns: []dnd.CombatTurn{{
Actor: "Storm",
TurnKind: dnd.CombatTurnKindTurn,
Actions: []dnd.CombatAction{{Category: dnd.CombatActionCategoryAttack, Declaration: "attacks", Targets: []string{"Minion"}}},
Summary: "Storm attacks",
SourceRefs: []source.SourceRef{{SourceID: doc.ID, StartUnitID: 10, EndUnitID: 10}},
}}}
result, err := normalizer.Normalize(context.Background(), contracts.TypedNormalizeRequest[dnd.CombatTurnList]{
Source: doc,
MergeOutput: contracts.MergeArtifact[dnd.CombatTurnList]{Value: input},
References: npcReferences(t),
})
if err != nil {
t.Fatalf("Normalize() error = %v", err)
}
turn := result.Value.CombatTurns[0]
if turn.Actor != "Aria" || turn.Actions[0].Targets[0] != "Goblin" {
t.Fatalf("operation-normalized turn = %#v, want Aria/Goblin", turn)
}
if metadata := normalizer.ManifestMetadata(); metadata["npc_registry_digest"] != nil || metadata["npc_count"] != nil {
t.Fatalf("singleton metadata = %#v, want no operation-varying NPC identity", metadata)
}
}
func TestNormalizeOrdersBySourcePositionAndCollapsesExactDuplicates(t *testing.T) {
doc := &source.SourceDocument{ID: "session", Units: []source.SourceUnit{{ID: 50}, {ID: 10}, {ID: 90}}}
first := validTurn("Aria", source.SourceRef{SourceID: doc.ID, StartUnitID: 50, EndUnitID: 50})