Collect independent correction validation findings
This commit is contained in:
87
internal/framework/runner/feedback.go
Normal file
87
internal/framework/runner/feedback.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package runner
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"gitea.maximumdirect.net/eric/audita/v3/internal/core/modulecatalog"
|
||||
"gitea.maximumdirect.net/eric/audita/v3/internal/framework/contracts"
|
||||
"gitea.maximumdirect.net/eric/audita/v3/internal/framework/proposal_generation"
|
||||
"gitea.maximumdirect.net/eric/audita/v3/internal/framework/proposals"
|
||||
"gitea.maximumdirect.net/eric/audita/v3/internal/framework/validators"
|
||||
validatormetadata "gitea.maximumdirect.net/eric/audita/v3/internal/validators/metadata"
|
||||
)
|
||||
|
||||
func feedbackPreview(input validateSectionCandidatesInput, candidate proposals.EnrichedCorrectionProposal) proposals.SegmentPreviewResult {
|
||||
if input.WorkingTranscript != nil {
|
||||
for i := range input.WorkingTranscript.Segments {
|
||||
segment := &input.WorkingTranscript.Segments[i]
|
||||
if segment.ID == candidate.TargetSegmentID {
|
||||
correction := candidate.CorrectionProposal
|
||||
if math.IsNaN(correction.Confidence) || correction.Confidence < 0 || correction.Confidence > 1 {
|
||||
correction.Confidence = 0.5
|
||||
}
|
||||
return proposals.PreviewProposalForSegment(segment, correction, input.Policy)
|
||||
}
|
||||
}
|
||||
}
|
||||
return proposals.PreviewProposalForSegment(nil, candidate.CorrectionProposal, input.Policy)
|
||||
}
|
||||
|
||||
// feedbackCandidates submits only candidates for which the validator has usable evidence.
|
||||
func feedbackCandidates(input validateSectionCandidatesInput, validator contracts.Validator, noEffect map[int]bool) []proposals.EnrichedCorrectionProposal {
|
||||
var result []proposals.EnrichedCorrectionProposal
|
||||
for _, candidate := range input.SectionEnriched {
|
||||
if noEffect[candidate.ProposalIndex] {
|
||||
continue
|
||||
}
|
||||
preview := feedbackPreview(input, candidate)
|
||||
usableSpan := candidate.OriginalText != ""
|
||||
target := candidate.TargetSegmentID > 0
|
||||
confidence := !math.IsNaN(candidate.Confidence) && candidate.Confidence >= 0 && candidate.Confidence <= 1
|
||||
var applicable bool
|
||||
switch validator.Name() {
|
||||
case "proposal_shape":
|
||||
applicable = true
|
||||
case "no_effect":
|
||||
applicable = usableSpan
|
||||
case "confidence_threshold":
|
||||
applicable = confidence
|
||||
case "original_text_presence":
|
||||
applicable = usableSpan && target
|
||||
case "protected_terms":
|
||||
applicable = usableSpan
|
||||
if input.Spec.ModuleKey == modulecatalog.KeyGlossary || input.Spec.ModuleKey == modulecatalog.KeySpokenWord {
|
||||
applicable = preview.Applicable
|
||||
}
|
||||
case "non_empty_resulting_segment":
|
||||
applicable = preview.Applicable || preview.SkipReason == proposals.SkipReasonEmptyResultingText
|
||||
default:
|
||||
if validatormetadata.ClassOf(validator) == validatormetadata.ExecutionClassLLMBacked {
|
||||
applicable = preview.Applicable
|
||||
} else {
|
||||
applicable = true
|
||||
}
|
||||
}
|
||||
if applicable {
|
||||
result = append(result, candidate)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// repairFindings extracts ordered, safe feedback for one candidate version.
|
||||
func repairFindings(index int, rejected []ValidatorRejectedChange) []proposal_generation.RepairFinding {
|
||||
var findings []proposal_generation.RepairFinding
|
||||
for _, decision := range rejected {
|
||||
if decision.ProposalIndex != index {
|
||||
continue
|
||||
}
|
||||
finding := proposal_generation.RepairFinding{Validator: decision.ValidatorName, Reason: decision.ReasonCode, Explanation: decision.Message}
|
||||
if decision.Disposition == validators.DispositionUnavailable {
|
||||
finding.Status = "unavailable"
|
||||
finding.Explanation = "assessment was unavailable"
|
||||
}
|
||||
findings = append(findings, finding)
|
||||
}
|
||||
return findings
|
||||
}
|
||||
Reference in New Issue
Block a user