Move NPC occurrences to their canonical namespace
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Package invariants validates normalized D&D NPC interaction artifacts.
|
||||
// Package invariants validates normalized D&D NPC occurrence artifacts.
|
||||
package invariants
|
||||
|
||||
import (
|
||||
@@ -10,17 +10,17 @@ import (
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd"
|
||||
interactionmodel "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/npcinteractions"
|
||||
interactionmodel "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/npcoccurrences"
|
||||
npcregistry "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/npcs/registry"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared/diagnostics"
|
||||
interactionshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcinteractions/shape"
|
||||
occurrenceshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcoccurrences/shape"
|
||||
)
|
||||
|
||||
const (
|
||||
Key = "normalize/dnd/npc-interactions/invariants"
|
||||
Key = "normalize/dnd/npc-occurrences/invariants"
|
||||
ReasonCode = "invalid_npc_interaction_normalization"
|
||||
policy = "dnd.npc_interactions.validator.normalized.v1"
|
||||
policy = "dnd.npc_occurrences.validator.normalized.v1"
|
||||
)
|
||||
|
||||
type Options struct{}
|
||||
@@ -35,7 +35,7 @@ var _ pipeline.CheckpointFingerprintProvider = (*Validator)(nil)
|
||||
|
||||
func New(_ Options, references ...contracts.ReferenceSet) (*Validator, error) {
|
||||
if len(references) > 1 {
|
||||
return nil, fmt.Errorf("NPC interaction invariants validator accepts at most one reference set")
|
||||
return nil, fmt.Errorf("NPC occurrence invariants validator accepts at most one reference set")
|
||||
}
|
||||
var referenceSet contracts.ReferenceSet
|
||||
if len(references) == 1 {
|
||||
@@ -77,7 +77,7 @@ func (v *Validator) CheckpointFingerprints() []pipeline.CheckpointFingerprint {
|
||||
}
|
||||
|
||||
func (v *Validator) Validate(_ context.Context, req contracts.TypedValidationRequest[dnd.NPCOccurrenceList]) (contracts.ValidationResult, error) {
|
||||
if interactionshape.Validate(req.Value) != nil {
|
||||
if occurrenceshape.Validate(req.Value) != nil {
|
||||
return contracts.ValidationResult{Approved: true}, nil
|
||||
}
|
||||
index := source.NewDocumentIndex(req.Source)
|
||||
@@ -85,14 +85,14 @@ func (v *Validator) Validate(_ context.Context, req contracts.TypedValidationReq
|
||||
return contracts.ValidationResult{Approved: true}, nil
|
||||
}
|
||||
if v == nil || v.npcResolver == nil {
|
||||
return contracts.ValidationResult{}, fmt.Errorf("NPC interaction invariants validator must not be nil")
|
||||
return contracts.ValidationResult{}, fmt.Errorf("NPC occurrence invariants validator must not be nil")
|
||||
}
|
||||
npcRegistry, err := v.npcResolver.Resolve(req.References)
|
||||
if err != nil {
|
||||
return contracts.ValidationResult{}, fmt.Errorf("resolve NPC registry: %w", err)
|
||||
}
|
||||
if !npcRegistry.Bound() {
|
||||
return contracts.ValidationResult{Approved: false, ReasonCode: ReasonCode, Message: "invalid NPC interaction normalization: NPC registry reference is required"}, nil
|
||||
return contracts.ValidationResult{Approved: false, ReasonCode: ReasonCode, Message: "invalid NPC occurrence normalization: NPC registry reference is required"}, nil
|
||||
}
|
||||
issues := issuesFor(shared.NewSourceRefOrderFromIndex(index), req.Value, npcRegistry)
|
||||
if len(issues) == 0 {
|
||||
@@ -101,7 +101,7 @@ func (v *Validator) Validate(_ context.Context, req contracts.TypedValidationReq
|
||||
return contracts.ValidationResult{
|
||||
Approved: false,
|
||||
ReasonCode: ReasonCode,
|
||||
Message: diagnostics.Aggregate("invalid NPC interaction normalization", issues),
|
||||
Message: diagnostics.Aggregate("invalid NPC occurrence normalization", issues),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
npcregistry "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/npcs/registry"
|
||||
)
|
||||
|
||||
func TestValidatorApprovesCanonicalNormalizedInteractions(t *testing.T) {
|
||||
func TestValidatorApprovesCanonicalNormalizedOccurrences(t *testing.T) {
|
||||
references := registryReferences(t, "Aria", "Borin")
|
||||
result, err := newValidator(t, references).Validate(context.Background(), request(references, normalizedList()))
|
||||
if err != nil || !result.Approved {
|
||||
@@ -143,9 +143,9 @@ func normalizedList() dnd.NPCOccurrenceList {
|
||||
|
||||
func cloneList(value dnd.NPCOccurrenceList) dnd.NPCOccurrenceList {
|
||||
copyValue := dnd.NPCOccurrenceList{Occurrences: make([]dnd.NPCOccurrence, len(value.Occurrences))}
|
||||
for index, interaction := range value.Occurrences {
|
||||
copyValue.Occurrences[index] = interaction
|
||||
copyValue.Occurrences[index].SourceRefs = append([]source.SourceRef(nil), interaction.SourceRefs...)
|
||||
for index, occurrence := range value.Occurrences {
|
||||
copyValue.Occurrences[index] = occurrence
|
||||
copyValue.Occurrences[index].SourceRefs = append([]source.SourceRef(nil), occurrence.SourceRefs...)
|
||||
}
|
||||
return copyValue
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Package registry validates D&D NPC interaction names against NPC grounding.
|
||||
// Package registry validates D&D NPC occurrence names against NPC grounding.
|
||||
package registry
|
||||
|
||||
import (
|
||||
@@ -10,13 +10,13 @@ import (
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd"
|
||||
npcregistry "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/npcs/registry"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared/diagnostics"
|
||||
interactionshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcinteractions/shape"
|
||||
occurrenceshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcoccurrences/shape"
|
||||
)
|
||||
|
||||
const (
|
||||
Key = "extract/dnd/npc-interactions/registry"
|
||||
Key = "extract/dnd/npc-occurrences/registry"
|
||||
ReasonCode = "invalid_npc_interaction_registry"
|
||||
policy = "dnd.npc_interactions.validator.registry.v1"
|
||||
policy = "dnd.npc_occurrences.validator.registry.v1"
|
||||
)
|
||||
|
||||
type Options struct{}
|
||||
@@ -31,7 +31,7 @@ var _ pipeline.CheckpointFingerprintProvider = (*Validator)(nil)
|
||||
|
||||
func New(_ Options, references ...contracts.ReferenceSet) (*Validator, error) {
|
||||
if len(references) > 1 {
|
||||
return nil, fmt.Errorf("NPC interaction registry validator accepts at most one reference set")
|
||||
return nil, fmt.Errorf("NPC occurrence registry validator accepts at most one reference set")
|
||||
}
|
||||
var referenceSet contracts.ReferenceSet
|
||||
if len(references) == 1 {
|
||||
@@ -73,11 +73,11 @@ func (v *Validator) CheckpointFingerprints() []pipeline.CheckpointFingerprint {
|
||||
}
|
||||
|
||||
func (v *Validator) Validate(_ context.Context, req contracts.TypedValidationRequest[dnd.NPCOccurrenceList]) (contracts.ValidationResult, error) {
|
||||
if interactionshape.Validate(req.Value) != nil {
|
||||
if occurrenceshape.Validate(req.Value) != nil {
|
||||
return contracts.ValidationResult{Approved: true}, nil
|
||||
}
|
||||
if v == nil || v.npcResolver == nil {
|
||||
return contracts.ValidationResult{}, fmt.Errorf("NPC interaction registry validator must not be nil")
|
||||
return contracts.ValidationResult{}, fmt.Errorf("NPC occurrence registry validator must not be nil")
|
||||
}
|
||||
npcRegistry, err := v.npcResolver.Resolve(req.References)
|
||||
if err != nil {
|
||||
@@ -107,7 +107,7 @@ func rejection(issues []string) contracts.ValidationResult {
|
||||
return contracts.ValidationResult{
|
||||
Approved: false,
|
||||
ReasonCode: ReasonCode,
|
||||
Message: diagnostics.Aggregate("invalid NPC interaction registry", issues),
|
||||
Message: diagnostics.Aggregate("invalid NPC occurrence registry", issues),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Package shape validates required D&D NPC interaction candidate fields.
|
||||
// Package shape validates required D&D NPC occurrence candidate fields.
|
||||
package shape
|
||||
|
||||
import (
|
||||
@@ -13,9 +13,9 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
Key = "extract/dnd/npc-interactions/shape"
|
||||
Key = "extract/dnd/npc-occurrences/shape"
|
||||
ReasonCode = "invalid_npc_interaction_shape"
|
||||
policy = "dnd.npc_interactions.validator.shape.v1"
|
||||
policy = "dnd.npc_occurrences.validator.shape.v1"
|
||||
)
|
||||
|
||||
type Options struct{}
|
||||
@@ -45,7 +45,7 @@ func Validate(value dnd.NPCOccurrenceList) error {
|
||||
if len(issues) == 0 {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("%s", diagnostics.Aggregate("invalid NPC interaction shape", issues))
|
||||
return fmt.Errorf("%s", diagnostics.Aggregate("invalid NPC occurrence shape", issues))
|
||||
}
|
||||
|
||||
func issuesFor(value dnd.NPCOccurrenceList) []string {
|
||||
@@ -1,4 +1,4 @@
|
||||
// Package sourcerefs validates D&D NPC interaction transcript evidence.
|
||||
// Package sourcerefs validates D&D NPC occurrence transcript evidence.
|
||||
package sourcerefs
|
||||
|
||||
import (
|
||||
@@ -10,13 +10,13 @@ import (
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared/diagnostics"
|
||||
interactionshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcinteractions/shape"
|
||||
occurrenceshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcoccurrences/shape"
|
||||
)
|
||||
|
||||
const (
|
||||
Key = "extract/dnd/npc-interactions/source_refs"
|
||||
Key = "extract/dnd/npc-occurrences/source_refs"
|
||||
ReasonCode = "invalid_npc_interaction_source_refs"
|
||||
policy = "dnd.npc_interactions.validator.source_refs.v2"
|
||||
policy = "dnd.npc_occurrences.validator.source_refs.v2"
|
||||
)
|
||||
|
||||
type Options struct{}
|
||||
@@ -36,9 +36,9 @@ func (v *Validator) CheckpointFingerprints() []pipeline.CheckpointFingerprint {
|
||||
|
||||
func (v *Validator) Validate(_ context.Context, req contracts.TypedValidationRequest[dnd.NPCOccurrenceList]) (contracts.ValidationResult, error) {
|
||||
if req.Stage == string(pipeline.StageExtract) && req.Chunk == nil {
|
||||
return contracts.ValidationResult{}, fmt.Errorf("NPC interaction source-reference validator requires the current extraction chunk")
|
||||
return contracts.ValidationResult{}, fmt.Errorf("NPC occurrence source-reference validator requires the current extraction chunk")
|
||||
}
|
||||
if interactionshape.Validate(req.Value) != nil {
|
||||
if occurrenceshape.Validate(req.Value) != nil {
|
||||
return contracts.ValidationResult{Approved: true}, nil
|
||||
}
|
||||
index := source.NewDocumentIndex(req.Source)
|
||||
@@ -63,7 +63,7 @@ func (v *Validator) Validate(_ context.Context, req contracts.TypedValidationReq
|
||||
return contracts.ValidationResult{
|
||||
Approved: false,
|
||||
ReasonCode: ReasonCode,
|
||||
Message: diagnostics.Aggregate("invalid NPC interaction source references", issues),
|
||||
Message: diagnostics.Aggregate("invalid NPC occurrence source references", issues),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Package sourcerelatedness warns about NPC interaction evidence unrelated to its NPC.
|
||||
// Package sourcerelatedness warns about NPC occurrence evidence unrelated to its NPC.
|
||||
package sourcerelatedness
|
||||
|
||||
import (
|
||||
@@ -10,14 +10,14 @@ import (
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared"
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared/diagnostics"
|
||||
interactionshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcinteractions/shape"
|
||||
occurrenceshape "gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/validate/npcoccurrences/shape"
|
||||
)
|
||||
|
||||
const (
|
||||
Key = "extract/dnd/npc-interactions/source_relatedness"
|
||||
Key = "extract/dnd/npc-occurrences/source_relatedness"
|
||||
WarningReasonCode = "npc_interaction_not_near_source"
|
||||
OmittedReasonCode = "npc_interaction_relatedness_warnings_omitted"
|
||||
policy = "dnd.npc_interactions.validator.source_relatedness.v2"
|
||||
policy = "dnd.npc_occurrences.validator.source_relatedness.v2"
|
||||
)
|
||||
|
||||
type Options struct{}
|
||||
@@ -36,7 +36,7 @@ func (v *Validator) CheckpointFingerprints() []pipeline.CheckpointFingerprint {
|
||||
}
|
||||
|
||||
func (v *Validator) Validate(_ context.Context, req contracts.TypedValidationRequest[dnd.NPCOccurrenceList]) (contracts.ValidationResult, error) {
|
||||
if interactionshape.Validate(req.Value) != nil {
|
||||
if occurrenceshape.Validate(req.Value) != nil {
|
||||
return contracts.ValidationResult{Approved: true}, nil
|
||||
}
|
||||
resolver, err := shared.NewCitationResolver(req.Source)
|
||||
@@ -59,12 +59,12 @@ func (v *Validator) Validate(_ context.Context, req contracts.TypedValidationReq
|
||||
warnings = append(warnings, contracts.Warning{
|
||||
Scope: fmt.Sprintf("occurrences[%d]", index),
|
||||
ReasonCode: WarningReasonCode,
|
||||
Message: fmt.Sprintf("NPC interaction name %s was not found in cited source text", diagnostics.Quote(occurrence.Name)),
|
||||
Message: fmt.Sprintf("NPC occurrence name %s was not found in cited source text", diagnostics.Quote(occurrence.Name)),
|
||||
})
|
||||
}
|
||||
return contracts.ValidationResult{
|
||||
Approved: true,
|
||||
Warnings: diagnostics.LimitWarnings(warnings, "npc_interactions", OmittedReasonCode),
|
||||
Warnings: diagnostics.LimitWarnings(warnings, "npc_occurrences", OmittedReasonCode),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd/shared/diagnostics"
|
||||
)
|
||||
|
||||
func TestValidatorUsesOnlyCurrentTranscriptAndWarnsOncePerInteraction(t *testing.T) {
|
||||
func TestValidatorUsesOnlyCurrentTranscriptAndWarnsOncePerOccurrence(t *testing.T) {
|
||||
value := dnd.NPCOccurrenceList{Occurrences: []dnd.NPCOccurrence{
|
||||
{NPCID: "npc:test", Name: "O'Rin Thorn", Kind: dnd.NPCOccurrenceKindDialogue, SourceRefs: []source.SourceRef{{SourceID: "session", StartUnitID: 1, EndUnitID: 1}}},
|
||||
{NPCID: "npc:test", Name: "Missing\nNPC", Kind: dnd.NPCOccurrenceKindMentioned, SourceRefs: []source.SourceRef{{SourceID: "session", StartUnitID: 2, EndUnitID: 2}, {SourceID: "session", StartUnitID: 2, EndUnitID: 2}}},
|
||||
@@ -53,9 +53,9 @@ func TestValidatorDefersMalformedShapeAndInvalidRanges(t *testing.T) {
|
||||
|
||||
func TestValidatorBoundsWarnings(t *testing.T) {
|
||||
count := diagnostics.MaxWarnings + 5
|
||||
interactions := make([]dnd.NPCOccurrence, count)
|
||||
for index := range interactions {
|
||||
interactions[index] = dnd.NPCOccurrence{
|
||||
occurrences := make([]dnd.NPCOccurrence, count)
|
||||
for index := range occurrences {
|
||||
occurrences[index] = dnd.NPCOccurrence{
|
||||
NPCID: "npc:test",
|
||||
Name: "Missing NPC",
|
||||
Kind: dnd.NPCOccurrenceKindMentioned,
|
||||
@@ -64,7 +64,7 @@ func TestValidatorBoundsWarnings(t *testing.T) {
|
||||
}
|
||||
result, err := New(Options{}).Validate(context.Background(), contracts.TypedValidationRequest[dnd.NPCOccurrenceList]{
|
||||
Source: &source.SourceDocument{ID: "session", Units: []source.SourceUnit{{ID: 1, Text: "The party waits."}}},
|
||||
Value: dnd.NPCOccurrenceList{Occurrences: interactions},
|
||||
Value: dnd.NPCOccurrenceList{Occurrences: occurrences},
|
||||
})
|
||||
if err != nil || !result.Approved {
|
||||
t.Fatalf("Validate() = %#v, %v", result, err)
|
||||
Reference in New Issue
Block a user