Files

108 lines
4.5 KiB
Go

// Package outcomes contains processing facts shared by proposal generation,
// validation, and orchestration. Presentation and filesystem concerns live elsewhere.
package outcomes
// OperationKind identifies one logical model operation. Validation input failures
// occur before a model call and therefore have no batch index.
type OperationKind string
const (
OperationProposal OperationKind = "proposal"
OperationValidation OperationKind = "validation"
OperationValidationInput OperationKind = "validation_input"
)
// Reference is the stable processing identity of an operation. Proposal indices
// are scoped to a module instance, while batch indices are local to a validator
// invocation within one section.
type Reference struct {
ModuleKey string `json:"module_key"`
ModuleInstance string `json:"module_instance"`
SectionIndex int `json:"section_index"`
Kind OperationKind `json:"operation"`
ValidatorName string `json:"validator_name,omitempty"`
ValidatorOrder *int `json:"validator_order,omitempty"`
BatchIndex *int `json:"batch_index,omitempty"`
}
// ExecutionCounts describe one terminal structured-client call. Available is
// false when an external client provides no execution facts; zero is then unknown.
type ExecutionCounts struct {
Available bool `json:"available"`
ProviderAttempts int `json:"provider_attempts"`
TransientRetries int `json:"transient_retries"`
StructuralRepairs int `json:"structural_repairs"`
RetriesExhausted bool `json:"retries_exhausted"`
HTTPStatus *int `json:"http_status,omitempty"`
}
// ReasonCode is a fixed, safe explanation category. Raw provider errors and
// prompt content are never stored in an operation outcome.
type ReasonCode string
const (
ReasonOperationTimeout ReasonCode = "operation_timeout"
ReasonCapacityExceeded ReasonCode = "capacity_exceeded"
ReasonTransportFailed ReasonCode = "transport_failed"
ReasonProviderResponseInvalid ReasonCode = "provider_response_invalid"
ReasonProviderFailed ReasonCode = "provider_failed"
ReasonInvalidOutputExhausted ReasonCode = "invalid_output_exhausted"
ReasonInvalidOutput ReasonCode = "invalid_output"
ReasonValidationInputTooLarge ReasonCode = "validation_input_too_large"
ReasonValidationDecisionsInvalid ReasonCode = "validation_decisions_invalid"
ReasonInputInvalid ReasonCode = "input_invalid"
ReasonSetupFailure ReasonCode = "setup_failure"
ReasonCanceled ReasonCode = "canceled"
ReasonInternalFailure ReasonCode = "internal_failure"
)
type RecoveryReason string
const (
RecoveryOutputRepaired RecoveryReason = "output_repaired"
RecoveryServiceRecovered RecoveryReason = "service_recovered"
RecoveryProposalsFiltered RecoveryReason = "proposals_filtered"
RecoveryValidationDecisionsFiltered RecoveryReason = "validation_decisions_filtered"
)
// FilteredProposal attributes a defective response item to its proposal identity.
// Ordinary editorial rejection is a decision, not a filtered proposal.
type FilteredProposal struct {
ProposalIndex int `json:"proposal_index"`
Reason ReasonCode `json:"reason"`
Count int `json:"count"`
}
// Operation is a compact terminal outcome. A successful operation may have one
// recovery with several reasons. A failed operation never has recovery reasons.
type Operation struct {
Reference Reference `json:"reference"`
Counts ExecutionCounts `json:"counts"`
Succeeded bool `json:"succeeded"`
FailureReason ReasonCode `json:"failure_reason,omitempty"`
RecoveryReasons []RecoveryReason `json:"recovery_reasons,omitempty"`
ProposalIndices []int `json:"proposal_indices,omitempty"`
Filtered []FilteredProposal `json:"filtered,omitempty"`
}
type WorkState string
const (
WorkNotStarted WorkState = "not_started"
WorkCompleted WorkState = "completed"
WorkInterrupted WorkState = "interrupted"
)
// ExecutionRecoveries classifies execution counts; callers decide whether their
// operation succeeded before recording these reasons.
func ExecutionRecoveries(counts ExecutionCounts) []RecoveryReason {
var reasons []RecoveryReason
if counts.StructuralRepairs > 0 {
reasons = append(reasons, RecoveryOutputRepaired)
}
if counts.TransientRetries > 0 {
reasons = append(reasons, RecoveryServiceRecovered)
}
return reasons
}