77 lines
3.2 KiB
Go
77 lines
3.2 KiB
Go
package domain
|
|
|
|
import (
|
|
"errors"
|
|
"git.cin.su/m/Assistant/contracts/work"
|
|
)
|
|
|
|
var ErrGovernedEvolution = errors.New("governed evolution gate failed")
|
|
|
|
func RunGovernedEvolution(needRef string, ops work.GovernedEvolutionOps) (work.GovernedEvolutionResult, error) {
|
|
result := work.GovernedEvolutionResult{NeedRef: needRef, Stages: []work.EvolutionRunStage{work.EvolutionNeedRecorded}}
|
|
if needRef == "" || ops.CreateCandidate == nil || ops.Evaluate == nil || ops.SandboxBuild == nil || ops.Benchmark == nil || ops.Promote == nil || ops.Rollback == nil || ops.LearningLedgerOutcome == nil {
|
|
return result, ErrGovernedEvolution
|
|
}
|
|
candidate, err := ops.CreateCandidate()
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
if candidate.ID == "" || candidate.ProposalRef == "" {
|
|
return result, ErrGovernedEvolution
|
|
}
|
|
result.CandidateRef = candidate.ID
|
|
result.Stages = append(result.Stages, work.EvolutionCandidateBuilt)
|
|
evaluation, err := ops.Evaluate(candidate)
|
|
if err != nil || !evaluation.ValidFor(candidate) {
|
|
return result, ErrGovernedEvolution
|
|
}
|
|
result.EvaluationRef = evaluation.CandidateRef
|
|
result.Stages = append(result.Stages, work.EvolutionIndependentlyEvaluated)
|
|
sandboxEvidence, err := ops.SandboxBuild(candidate)
|
|
if err != nil || sandboxEvidence == "" {
|
|
return result, ErrGovernedEvolution
|
|
}
|
|
candidate.SandboxEvidenceRefs = append(candidate.SandboxEvidenceRefs, sandboxEvidence)
|
|
result.EvidenceRefs = append(result.EvidenceRefs, sandboxEvidence)
|
|
result.Stages = append(result.Stages, work.EvolutionSandboxed)
|
|
benchmarkEvidence, passed, err := ops.Benchmark(candidate)
|
|
if err != nil || !passed || benchmarkEvidence == "" {
|
|
result = rollbackEvolution(result, candidate, ops)
|
|
return result, ErrGovernedEvolution
|
|
}
|
|
candidate.BenchmarkEvidenceRefs = append(candidate.BenchmarkEvidenceRefs, benchmarkEvidence)
|
|
result.EvidenceRefs = append(result.EvidenceRefs, benchmarkEvidence)
|
|
result.Stages = append(result.Stages, work.EvolutionBenchmarked)
|
|
if ops.Canary != nil {
|
|
canaryEvidence, passed, canaryErr := ops.Canary(candidate)
|
|
if canaryErr != nil || !passed || canaryEvidence == "" {
|
|
result = rollbackEvolution(result, candidate, ops)
|
|
return result, ErrGovernedEvolution
|
|
}
|
|
result.EvidenceRefs = append(result.EvidenceRefs, canaryEvidence)
|
|
result.Stages = append(result.Stages, work.EvolutionCanaried)
|
|
}
|
|
promotionRef, err := ops.Promote(candidate, evaluation)
|
|
if err != nil || promotionRef == "" {
|
|
result = rollbackEvolution(result, candidate, ops)
|
|
return result, ErrGovernedEvolution
|
|
}
|
|
result.Promoted = true
|
|
result.Stages = append(result.Stages, work.EvolutionPromoted)
|
|
result.LearningLedgerOutcomeRef, err = ops.LearningLedgerOutcome(result)
|
|
if err != nil || result.LearningLedgerOutcomeRef == "" {
|
|
return result, ErrGovernedEvolution
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func rollbackEvolution(result work.GovernedEvolutionResult, candidate work.EvolutionCandidate, ops work.GovernedEvolutionOps) work.GovernedEvolutionResult {
|
|
ref, err := ops.Rollback(candidate)
|
|
if err == nil && ref != "" {
|
|
result.RollbackRef = ref
|
|
result.Stages = append(result.Stages, work.EvolutionRolledBack)
|
|
result.LearningLedgerOutcomeRef, _ = ops.LearningLedgerOutcome(result)
|
|
}
|
|
return result
|
|
}
|