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" ) // feedbackCandidates submits only candidates for which the validator has usable evidence. func feedbackCandidates(input validateSectionCandidatesInput, validator contracts.Validator, noEffect map[int]bool, evidence contracts.ValidationRequest) []proposals.EnrichedCorrectionProposal { var result []proposals.EnrichedCorrectionProposal for _, candidate := range input.SectionEnriched { if noEffect[candidate.ProposalIndex] { continue } 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 { preview := evidence.Preview(candidate) applicable = preview.Applicable || preview.SkipReason == proposals.SkipReasonEmptyResultingText } case "non_empty_resulting_segment": preview := evidence.Preview(candidate) applicable = preview.Applicable || preview.SkipReason == proposals.SkipReasonEmptyResultingText default: if validatormetadata.ClassOf(validator) == validatormetadata.ExecutionClassLLMBacked { applicable = evidence.Preview(candidate).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 }