Collect independent correction validation findings

This commit is contained in:
2026-11-11 04:23:34 +00:00
parent 9fd36001b4
commit a5003a1e52
6 changed files with 220 additions and 6 deletions

View File

@@ -613,6 +613,9 @@ func validateSectionCandidates(ctx context.Context, input validateSectionCandida
operations := make([]outcomes.Operation, 0)
filtered := make([]outcomes.FilteredProposal, 0)
eligible := append([]proposals.EnrichedCorrectionProposal(nil), input.SectionEnriched...)
feedback := input.Spec.Settings.LLM.CorrectionRepairAttempts > 0
blocked := make(map[int]bool)
noEffect := make(map[int]bool)
var interactionWriter *llmDiagnosticsWriterAdapter
for validatorOrder, validator := range input.Validators {
@@ -633,10 +636,14 @@ func validateSectionCandidates(ctx context.Context, input validateSectionCandida
diagnosticsWriter = interactionWriter
}
submitted := eligible
if feedback {
submitted = feedbackCandidates(input, validator, noEffect)
}
vResult, err := validator.Validate(ctx, contracts.ValidationRequest{
StageIndex: &input.Spec.Index, StageID: input.Spec.ID,
WorkingTranscript: input.WorkingTranscript,
CandidateProposal: eligible,
CandidateProposal: submitted,
ModuleKey: input.Spec.ModuleKey,
ModuleInstance: input.Spec.InstanceName,
SectionIndex: input.SectionIndex,
@@ -654,9 +661,9 @@ func validateSectionCandidates(ctx context.Context, input validateSectionCandida
var decisionErr error
if err != nil {
decisionErr = validators.EnforcePartialDecisionCardinality(eligible, vResult.Decisions)
decisionErr = validators.EnforcePartialDecisionCardinality(submitted, vResult.Decisions)
} else {
decisionErr = validators.EnforceDecisionCardinality(eligible, vResult.Decisions)
decisionErr = validators.EnforceDecisionCardinality(submitted, vResult.Decisions)
}
if decisionErr != nil {
return validateSectionCandidatesResult{
@@ -664,13 +671,28 @@ func validateSectionCandidates(ctx context.Context, input validateSectionCandida
}, fmt.Errorf("validator %q cardinality failed: %w", validator.Name(), errors.Join(err, decisionErr))
}
nextEligible := make([]proposals.EnrichedCorrectionProposal, 0, len(eligible))
byIndex := make(map[int]proposals.EnrichedCorrectionProposal, len(eligible))
for _, p := range eligible {
nextEligible := make([]proposals.EnrichedCorrectionProposal, 0, len(submitted))
byIndex := make(map[int]proposals.EnrichedCorrectionProposal, len(submitted))
for _, p := range submitted {
byIndex[p.ProposalIndex] = p
}
for _, d := range vResult.Decisions {
if feedback && validator.Name() == "original_text_presence" && d.Approved {
preview := feedbackPreview(input, byIndex[d.ProposalIndex])
if preview.SkipReason == proposals.SkipReasonAmbiguousOriginal {
d.Approved = false
d.Disposition = validators.DispositionRejected
d.ReasonCode = string(proposals.SkipReasonAmbiguousOriginal)
d.Message = "original_text matches multiple locations in the target segment"
}
}
if !d.Approved {
blocked[d.ProposalIndex] = true
if d.ReasonCode == validators.ReasonNoEffect {
noEffect[d.ProposalIndex] = true
}
}
decisions = append(decisions, ValidatorDecisionRecord{
ValidatorName: validator.Name(),
ProposalIndex: d.ProposalIndex,
@@ -714,6 +736,14 @@ func validateSectionCandidates(ctx context.Context, input validateSectionCandida
eligible = nextEligible
}
if feedback {
eligible = eligible[:0]
for _, candidate := range input.SectionEnriched {
if !blocked[candidate.ProposalIndex] {
eligible = append(eligible, candidate)
}
}
}
return validateSectionCandidatesResult{
approved: eligible,
decisions: decisions,