JuliusBrussee/caveman · error
session-value artifact confidence policy invalid
Error message
session-value artifact confidence policy invalid
What it means
Confidence-policy constants are range-checked: QualityUncertaintyZ must be finite and in (0, 5] (the z-score used for conservative quality estimates) and MaxInversePropensity must be finite and in [1, 100] (the importance-weighting cap). NaN, infinities, or out-of-range values would make exploration corrections unbounded or degenerate, so they are rejected.
Source
Thrown at proxy/routing/session_value.go:188
}
if artifact.PolicyVersion <= 0 || artifact.RouterVersion != SessionValueRouterVersion || strings.TrimSpace(artifact.EstimatorVersion) == "" {
return errors.New("session-value artifact version identity invalid")
}
if !validCompactPoolHash(artifact.CandidatePoolHash) || artifact.CandidatePoolHash != candidatePoolHash {
return errors.New("session-value artifact candidate pool mismatch")
}
if !validSHA256Ref(artifact.TrainingManifestHash) || strings.TrimSpace(artifact.TrainingExtractor) == "" || strings.TrimSpace(artifact.OutcomeContractVersion) == "" {
return errors.New("session-value artifact training lineage invalid")
}
if artifact.ValidFrom.IsZero() || artifact.ValidUntil.IsZero() || !artifact.ValidUntil.After(artifact.ValidFrom) || now.Before(artifact.ValidFrom) || !now.Before(artifact.ValidUntil) {
return errors.New("session-value artifact outside validity window")
}
if artifact.RollbackParentHash != "" && (!validSHA256Ref(artifact.RollbackParentHash) || artifact.RollbackParentHash == artifact.ArtifactHash) {
return errors.New("session-value artifact rollback lineage invalid")
}
if !finite(artifact.QualityUncertaintyZ) || artifact.QualityUncertaintyZ <= 0 || artifact.QualityUncertaintyZ > 5 ||
!finite(artifact.MaxInversePropensity) || artifact.MaxInversePropensity < 1 || artifact.MaxInversePropensity > 100 {
return errors.New("session-value artifact confidence policy invalid")
}
featureNames := SessionValueFeatureNames()
if len(artifact.FeatureSpecs) != len(featureNames) || len(artifact.Actions) == 0 {
return errors.New("session-value artifact has no features or actions")
}
for i, spec := range artifact.FeatureSpecs {
if spec.Name != featureNames[i] || (i > 0 && artifact.FeatureSpecs[i-1].Name >= spec.Name) {
return errors.New("session-value artifact feature vocabulary or order invalid")
}
if spec.Name == "turn_index" && !spec.Required {
return errors.New("session-value artifact must require turn_index")
}
if !finite(spec.Mean) || !finite(spec.Scale) || spec.Scale <= 0 || !finite(spec.Min) || !finite(spec.Max) || spec.Min < 0 || spec.Max < spec.Min {
return fmt.Errorf("session-value feature %q bounds invalid", spec.Name)
}
}
seenActions := map[string]struct{}{}
artifactPool := make([]Candidate, 0, len(artifact.Actions))View on GitHub (pinned to 766dce6b13)
Solutions
- Clamp and validate both constants in the trainer: 0 < QualityUncertaintyZ <= 5 and 1 <= MaxInversePropensity <= 100.
- Fail the training job when any artifact float is non-finite (math.IsNaN / math.IsInf) instead of emitting it.
- Regenerate and re-seal the artifact after fixing the estimation code.
Example fix
// before
{
"quality_uncertainty_z": 0,
"max_inverse_propensity": 1000
}
// after
{
"quality_uncertainty_z": 1.96,
"max_inverse_propensity": 20
} Defensive patterns
Strategy: validation
Validate before calling
// Before validation: reject non-finite and out-of-range confidence constants.
func finite(v float64) bool { return !math.IsNaN(v) && !math.IsInf(v, 0) }
if !finite(artifact.QualityUncertaintyZ) || artifact.QualityUncertaintyZ <= 0 || artifact.QualityUncertaintyZ > 5 ||
!finite(artifact.MaxInversePropensity) || artifact.MaxInversePropensity < 1 || artifact.MaxInversePropensity > 100 {
return errors.New("confidence policy out of range: need 0 < z <= 5 and 1 <= max_inverse_propensity <= 100")
} Type guard
func confidencePolicySane(a routing.SessionValuePolicyArtifact) bool {
return finite(a.QualityUncertaintyZ) && a.QualityUncertaintyZ > 0 && a.QualityUncertaintyZ <= 5 &&
finite(a.MaxInversePropensity) && a.MaxInversePropensity >= 1 && a.MaxInversePropensity <= 100
} Prevention
- Fail training when any emitted float is NaN or Inf (math.IsNaN/math.IsInf sweep before serialization).
- Validate confidence constants against the (0,5] and [1,100] ranges in trainer unit tests.
- Never hand-edit these constants in shipped artifacts; regenerate from the trainer.
When it happens
Trigger: The trainer emitting NaN or Inf into the JSON (division by zero during estimation, empty-data covariance); QualityUncertaintyZ set to 0 or negative; MaxInversePropensity set to 0 (weights everything out) or above 100 (explodes estimator variance).
Common situations: Numerical instability in offline training runs; struct defaults never overwritten by the fitting step; downstream JSON handling turning null/garbage into non-finite floats.
Related errors
- session-value artifact version identity invalid
- session-value artifact schema mismatch
- session-value artifact tenant scope mismatch
- session-value artifact candidate pool mismatch
- session-value artifact outside validity window
AI-assisted analysis of JuliusBrussee/caveman@766dce6b13 (2026-08-18).
Data as JSON: /api/errors/8370908e17f9e108.
Report an issue: GitHub.