Improve D&D validation reliability

This commit is contained in:
2026-08-29 01:24:45 +00:00
parent 4da9360d74
commit 917d150279
55 changed files with 1300 additions and 565 deletions

View File

@@ -16,7 +16,7 @@ import (
const (
Key = "extract/dnd/enemy-events/engagements"
ReasonCode = "duplicate_enemy_engagement"
policy = "dnd.enemy_events.validator.engagements.v1"
policy = "dnd.enemy_events.validator.engagements.v2"
)
type Options struct{}
@@ -38,7 +38,9 @@ func (v *Validator) Validate(_ context.Context, req contracts.TypedValidationReq
if enemyeventshape.Validate(req.Value) != nil {
return contracts.ValidationResult{Approved: true}, nil
}
seen := make(map[string]struct{})
seen := make(map[string]dnd.EnemyEvent)
issues := make([]string, 0)
var corrections diagnostics.Corrections
for _, event := range req.Value.Events {
if event.Kind != dnd.EnemyEventKindEngaged {
continue
@@ -47,17 +49,24 @@ func (v *Validator) Validate(_ context.Context, req contracts.TypedValidationReq
if identity == "" {
continue
}
if _, found := seen[identity]; found {
return contracts.ValidationResult{
Approved: false,
ReasonCode: ReasonCode,
Message: diagnostics.Aggregate("duplicate enemy engagement", []string{
fmt.Sprintf("subject %s has more than one engagement in one combat scene", diagnostics.Quote(event.Name)),
}),
CorrectionGuidance: "Return at most one engagement event for each contextual enemy name within the same combat scene.",
}, nil
if first, found := seen[identity]; found {
issues = append(issues, fmt.Sprintf("subject %s has more than one engagement in one combat scene", diagnostics.Quote(event.Name)))
corrections.Add(
"duplicate-subject",
"Return at most one `engaged` event for each contextual enemy name within this combat scene; keep the source ranges together on that one event.",
fmt.Sprintf("Affected enemy %s: first engagement %s; additional engagement %s.", diagnostics.Quote(event.Name), diagnostics.SourceRange(first.SourceRefs), diagnostics.SourceRange(event.SourceRefs)),
)
continue
}
seen[identity] = struct{}{}
seen[identity] = event
}
if len(issues) != 0 {
return contracts.ValidationResult{
Approved: false,
ReasonCode: ReasonCode,
Message: diagnostics.Aggregate("duplicate enemy engagement", issues),
CorrectionGuidance: corrections.Guidance("Correct every duplicate enemy engagement and return the complete replacement event list"),
}, nil
}
return contracts.ValidationResult{Approved: true}, nil
}