Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96687140ce | ||
|
|
b282038949 |
@@ -0,0 +1,10 @@
|
||||
package main
|
||||
|
||||
import "net/http"
|
||||
|
||||
func main() {
|
||||
_ = http.ListenAndServe(":8088", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write([]byte("lifeboat-ready\n"))
|
||||
}))
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package work
|
||||
|
||||
type EvolutionChangeLevel string
|
||||
|
||||
const (
|
||||
EvolutionKnowledge EvolutionChangeLevel = "KNOWLEDGE"
|
||||
EvolutionBehavior EvolutionChangeLevel = "BEHAVIOR"
|
||||
EvolutionCapability EvolutionChangeLevel = "CAPABILITY"
|
||||
EvolutionCore EvolutionChangeLevel = "CORE"
|
||||
)
|
||||
|
||||
type EvolutionCandidate struct {
|
||||
ID string
|
||||
ProposalRef string
|
||||
ChangeLevel EvolutionChangeLevel
|
||||
CreatorIdentity string
|
||||
BaseVersionRef string
|
||||
CandidateVersionRef string
|
||||
MustNotWorsen []string
|
||||
SandboxEvidenceRefs []EvidenceRef
|
||||
BenchmarkEvidenceRefs []EvidenceRef
|
||||
RollbackRef string
|
||||
State string
|
||||
}
|
||||
type EvolutionEvaluation struct {
|
||||
CandidateRef string
|
||||
EvaluatorIdentity string
|
||||
Approved bool
|
||||
EvidenceRefs []EvidenceRef
|
||||
MustNotWorsenPassed bool
|
||||
RecordedAtUnixMillis int64
|
||||
}
|
||||
|
||||
func (e EvolutionEvaluation) ValidFor(c EvolutionCandidate) bool {
|
||||
return e.CandidateRef == c.ID && e.EvaluatorIdentity != "" && e.EvaluatorIdentity != c.CreatorIdentity && e.Approved && e.MustNotWorsenPassed && len(e.EvidenceRefs) > 0 && e.RecordedAtUnixMillis > 0
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
{"task_file":"dev/tasks/GEN2-020-separate-execution-receipt-from-verified-world-outcome.json","task_id":"GEN2-020","task_revision":1}
|
||||
{"task_file":"dev/tasks/GEN2-022-wire-governed-self-evolution-loop-using-existing-development-gates.json","task_id":"GEN2-022","task_revision":1}
|
||||
@@ -0,0 +1,7 @@
|
||||
package domain
|
||||
|
||||
import "git.cin.su/m/Assistant/contracts/work"
|
||||
|
||||
func PromoteEvolution(c work.EvolutionCandidate, e work.EvolutionEvaluation) bool {
|
||||
return e.ValidFor(c) && c.ProposalRef != "" && c.RollbackRef != "" && len(c.SandboxEvidenceRefs) > 0 && len(c.BenchmarkEvidenceRefs) > 0
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package domain_test
|
||||
|
||||
import (
|
||||
"git.cin.su/m/Assistant/contracts/work"
|
||||
"git.cin.su/m/Assistant/modules/work/domain"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEvolutionRequiresIndependentEvaluatorAndRollbackEvidence(t *testing.T) {
|
||||
c := work.EvolutionCandidate{ID: "c", ProposalRef: "p", ChangeLevel: work.EvolutionBehavior, CreatorIdentity: "creator", RollbackRef: "rollback", SandboxEvidenceRefs: []work.EvidenceRef{"sandbox"}, BenchmarkEvidenceRefs: []work.EvidenceRef{"benchmark"}}
|
||||
e := work.EvolutionEvaluation{CandidateRef: "c", EvaluatorIdentity: "creator", Approved: true, MustNotWorsenPassed: true, EvidenceRefs: []work.EvidenceRef{"eval"}, RecordedAtUnixMillis: 1}
|
||||
if domain.PromoteEvolution(c, e) {
|
||||
t.Fatal("creator promoted own change")
|
||||
}
|
||||
e.EvaluatorIdentity = "independent"
|
||||
if !domain.PromoteEvolution(c, e) {
|
||||
t.Fatal("independently evaluated candidate rejected")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package supervisor
|
||||
|
||||
type ReleaseState string
|
||||
|
||||
const (
|
||||
ReleaseCandidate ReleaseState = "CANDIDATE"
|
||||
ReleaseHealthy ReleaseState = "HEALTHY"
|
||||
ReleaseFailed ReleaseState = "FAILED"
|
||||
ReleaseRolledBack ReleaseState = "ROLLED_BACK"
|
||||
)
|
||||
|
||||
type Release struct {
|
||||
ID string
|
||||
Version string
|
||||
State ReleaseState
|
||||
LastKnownGood bool
|
||||
}
|
||||
type Observation struct {
|
||||
ReleaseID string
|
||||
Ready bool
|
||||
Reason string
|
||||
ObservedAtUnixMillis int64
|
||||
}
|
||||
type Lifeboat struct {
|
||||
Current Release
|
||||
LastKnownGood Release
|
||||
Observations []Observation
|
||||
}
|
||||
|
||||
func (l *Lifeboat) Start(candidate Release) bool {
|
||||
if candidate.ID == "" || candidate.Version == "" {
|
||||
return false
|
||||
}
|
||||
candidate.State = ReleaseCandidate
|
||||
l.Current = candidate
|
||||
return true
|
||||
}
|
||||
func (l *Lifeboat) Record(o Observation) bool {
|
||||
if o.ReleaseID == "" {
|
||||
return false
|
||||
}
|
||||
l.Observations = append(l.Observations, o)
|
||||
if o.ReleaseID != l.Current.ID {
|
||||
return true
|
||||
}
|
||||
if o.Ready {
|
||||
l.Current.State = ReleaseHealthy
|
||||
l.Current.LastKnownGood = true
|
||||
l.LastKnownGood = l.Current
|
||||
} else {
|
||||
l.Current.State = ReleaseFailed
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (l *Lifeboat) Rollback() bool {
|
||||
if l.LastKnownGood.ID == "" {
|
||||
return false
|
||||
}
|
||||
l.Current = l.LastKnownGood
|
||||
l.Current.State = ReleaseRolledBack
|
||||
return true
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package supervisor_test
|
||||
|
||||
import (
|
||||
"git.cin.su/m/Assistant/runtime/supervisor"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLifeboatRollsBackCandidateToLastKnownGood(t *testing.T) {
|
||||
l := supervisor.Lifeboat{}
|
||||
l.Start(supervisor.Release{ID: "good", Version: "1"})
|
||||
l.Record(supervisor.Observation{ReleaseID: "good", Ready: true})
|
||||
l.Start(supervisor.Release{ID: "candidate", Version: "2"})
|
||||
l.Record(supervisor.Observation{ReleaseID: "candidate", Ready: false})
|
||||
if !l.Rollback() || l.Current.ID != "good" || l.Current.State != supervisor.ReleaseRolledBack {
|
||||
t.Fatalf("%#v", l)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user