Add durable validation provenance
This commit is contained in:
@@ -68,13 +68,14 @@ type RunInput struct {
|
||||
}
|
||||
|
||||
type RunOutput struct {
|
||||
Manifest artifacts.RunManifest `json:"manifest"`
|
||||
ChunkPlan *artifacts.ChunkPlanSummary `json:"chunk_plan,omitempty"`
|
||||
NormalizeOutputs []contracts.SerializedOutput `json:"normalize_outputs,omitempty"`
|
||||
Rejected []contracts.RejectedOutput `json:"rejected,omitempty"`
|
||||
Warnings []contracts.Warning `json:"warnings,omitempty"`
|
||||
OutputFiles []contracts.OutputFile `json:"-"`
|
||||
CheckpointEvents []CheckpointEvent `json:"checkpoint_events,omitempty"`
|
||||
Manifest artifacts.RunManifest `json:"manifest"`
|
||||
ChunkPlan *artifacts.ChunkPlanSummary `json:"chunk_plan,omitempty"`
|
||||
NormalizeOutputs []contracts.SerializedOutput `json:"normalize_outputs,omitempty"`
|
||||
Rejected []contracts.RejectedOutput `json:"rejected,omitempty"`
|
||||
Warnings []contracts.Warning `json:"warnings,omitempty"`
|
||||
OutputFiles []contracts.OutputFile `json:"-"`
|
||||
CheckpointEvents []CheckpointEvent `json:"checkpoint_events,omitempty"`
|
||||
ValidationSummaries []artifacts.ValidationSummary `json:"validation_summaries,omitempty"`
|
||||
}
|
||||
|
||||
func (r *Runner) Run(ctx context.Context, input RunInput) (output RunOutput, err error) {
|
||||
@@ -241,6 +242,9 @@ func (r *Runner) Run(ctx context.Context, input RunInput) (output RunOutput, err
|
||||
if chunkResult.rejection != nil {
|
||||
output.Rejected = append(output.Rejected, *chunkResult.rejection)
|
||||
}
|
||||
if chunkResult.validation != nil {
|
||||
output.ValidationSummaries = append(output.ValidationSummaries, artifacts.CloneValidationSummary(*chunkResult.validation))
|
||||
}
|
||||
output.Warnings = append(output.Warnings, chunkResult.warnings...)
|
||||
chunkDebugPayload := map[string]any{
|
||||
"cache_mode": chunkMode,
|
||||
@@ -297,6 +301,8 @@ func (r *Runner) Run(ctx context.Context, input RunInput) (output RunOutput, err
|
||||
|
||||
if len(output.Rejected) > 0 {
|
||||
output.Manifest.ValidationStatus = "rejected"
|
||||
} else if hasIncompleteValidation(output.ValidationSummaries) {
|
||||
output.Manifest.ValidationStatus = "incomplete"
|
||||
} else {
|
||||
output.Manifest.ValidationStatus = "approved"
|
||||
}
|
||||
@@ -401,6 +407,15 @@ func (r *Runner) Run(ctx context.Context, input RunInput) (output RunOutput, err
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func hasIncompleteValidation(summaries []artifacts.ValidationSummary) bool {
|
||||
for _, summary := range summaries {
|
||||
if summary.Status == "incomplete" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *Runner) runPreparedSteps(ctx context.Context, input RunInput, checkpoints CheckpointRecorder, loader CheckpointLoader, doc *source.SourceDocument, sourceInput contracts.LLMInputMaterial, sessionID string, chunks []source.Chunk, output *RunOutput) error {
|
||||
for _, step := range input.Prepared.Steps {
|
||||
stepInput := input
|
||||
@@ -720,6 +735,9 @@ func populateOutputManifest(output *RunOutput) {
|
||||
}
|
||||
output.Manifest.NormalizedOutputs = normalizedOutputManifests(output.NormalizeOutputs)
|
||||
output.Manifest.RejectedOutputs = rejectedOutputManifests(output.Rejected)
|
||||
if len(output.ValidationSummaries) > 0 {
|
||||
output.Manifest.ValidationSummaries = cloneValidationSummaries(output.ValidationSummaries)
|
||||
}
|
||||
if len(output.CheckpointEvents) > 0 {
|
||||
decisions := make([]artifacts.CheckpointDecisionManifest, 0, len(output.CheckpointEvents))
|
||||
for _, event := range output.CheckpointEvents {
|
||||
@@ -769,6 +787,7 @@ func rejectedOutputManifests(rejected []contracts.RejectedOutput) []artifacts.Re
|
||||
Message: output.Message,
|
||||
AttemptCount: output.AttemptCount,
|
||||
DiagnosticArtifactPath: output.DiagnosticArtifactPath,
|
||||
Validation: cloneValidationSummaryPtr(output.Validation),
|
||||
})
|
||||
}
|
||||
return manifests
|
||||
@@ -1027,7 +1046,31 @@ func cloneRejectedOutputs(rejected []contracts.RejectedOutput) []contracts.Rejec
|
||||
if len(rejected) == 0 {
|
||||
return nil
|
||||
}
|
||||
return append([]contracts.RejectedOutput(nil), rejected...)
|
||||
cloned := make([]contracts.RejectedOutput, len(rejected))
|
||||
for index, item := range rejected {
|
||||
cloned[index] = item
|
||||
cloned[index].Validation = cloneValidationSummaryPtr(item.Validation)
|
||||
}
|
||||
return cloned
|
||||
}
|
||||
|
||||
func cloneValidationSummaryPtr(summary *artifacts.ValidationSummary) *artifacts.ValidationSummary {
|
||||
if summary == nil {
|
||||
return nil
|
||||
}
|
||||
cloned := artifacts.CloneValidationSummary(*summary)
|
||||
return &cloned
|
||||
}
|
||||
|
||||
func cloneValidationSummaries(summaries []artifacts.ValidationSummary) []artifacts.ValidationSummary {
|
||||
if len(summaries) == 0 {
|
||||
return nil
|
||||
}
|
||||
cloned := make([]artifacts.ValidationSummary, len(summaries))
|
||||
for index, summary := range summaries {
|
||||
cloned[index] = artifacts.CloneValidationSummary(summary)
|
||||
}
|
||||
return cloned
|
||||
}
|
||||
|
||||
func timePtr(t time.Time) *time.Time {
|
||||
|
||||
Reference in New Issue
Block a user