Files
audita/internal/framework/validators/section.go

62 lines
1.8 KiB
Go
Raw Normal View History

package validators
import (
"math"
"gitea.maximumdirect.net/eric/audita/v3/internal/core/schema"
"gitea.maximumdirect.net/eric/audita/v3/internal/framework/proposals"
)
// SectionLookup indexes the immutable source section shared by validation
// and revalidation. Application checks its own, changing transcript.
type SectionLookup struct {
segments []schema.Segment
positions map[int]int
}
func NewSectionLookup(transcript *schema.Transcript) *SectionLookup {
section := &SectionLookup{}
if transcript != nil {
section.segments = transcript.Segments
section.positions = make(map[int]int, len(section.segments))
for i, segment := range section.segments {
section.positions[segment.ID] = i
}
}
return section
}
func (s *SectionLookup) Position(id int) (int, bool) {
position, ok := s.positions[id]
return position, ok
}
func (r Request) sectionLookup() *SectionLookup {
if r.Section != nil {
return r.Section
}
return NewSectionLookup(r.WorkingTranscript)
}
// Preview reuses the replacement preview for this proposal index within one
// validation pass. A revision starts a new pass with its own preview map.
func (r Request) Preview(candidate proposals.EnrichedCorrectionProposal) proposals.SegmentPreviewResult {
if preview, ok := r.Previews[candidate.ProposalIndex]; ok {
return preview
}
section := r.sectionLookup()
var segment *schema.Segment
if position, ok := section.Position(candidate.TargetSegmentID); ok {
segment = &section.segments[position]
}
correction := candidate.CorrectionProposal
if r.IndependentEvidence && (math.IsNaN(correction.Confidence) || correction.Confidence < 0 || correction.Confidence > 1) {
correction.Confidence = 0.5
}
preview := proposals.PreviewProposalForSegment(segment, correction, r.ReplacementPolicy)
if r.Previews != nil {
r.Previews[candidate.ProposalIndex] = preview
}
return preview
}