Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96687140ce | ||
|
|
b282038949 | ||
|
|
4de506a2af | ||
|
|
36272b9036 | ||
|
|
a779568622 | ||
|
|
243a11490b | ||
|
|
26207d93ef | ||
|
|
42871f2e47 | ||
|
|
6ea1d4b729 | ||
|
|
c6d1ebf36f | ||
|
|
25d8d6d219 | ||
|
|
6cbef9af41 | ||
|
|
2fe9802e5a | ||
|
|
0882df3ad2 | ||
|
|
0acbe53fad |
@@ -533,7 +533,7 @@ func main() {
|
||||
log.Printf("interaction principal history loaded: %d utterances", len(recentUserHistory))
|
||||
}
|
||||
conversationHistory = append(conversationHistory, recentUserHistory...)
|
||||
personalMemory := interactiondomain.CompilePersonalMemory(conversationHistory)
|
||||
gen2Context := interactiondomain.BuildGen2Context(conversationHistory)
|
||||
if !creativeUserRequest && locationReply == "" {
|
||||
if continuation := interactiondomain.ContinueLocalSearch(effectiveTaskMessage, conversationHistory); continuation != "" {
|
||||
continuationMessage = continuation
|
||||
@@ -829,7 +829,7 @@ func main() {
|
||||
reply, backed := renderResearchReply(searchQuery, result, researchErr)
|
||||
if !backed && cognitiveAvailable {
|
||||
answerCtx, cancelAnswer := context.WithTimeout(r.Context(), 12*time.Second)
|
||||
answer, answerErr := cognitiveClient.AnswerStableKnowledge(answerCtx, session, part, personalMemory.ContextText(), cognitive.TaskMeaning{
|
||||
answer, answerErr := cognitiveClient.AnswerStableKnowledge(answerCtx, session, part, gen2Context.Text, cognitive.TaskMeaning{
|
||||
SpeechAct: string(semantic.Interpretation.SpeechAct), CapabilityHints: toCapabilityKinds(semantic.CapabilityHints), RequestedOutcome: semantic.Interpretation.RequestedOutcome, InformationRequestKind: semantic.InformationRequestKind, ConfidenceMillis: semantic.Interpretation.ConfidenceMillis,
|
||||
})
|
||||
cancelAnswer()
|
||||
@@ -869,7 +869,7 @@ func main() {
|
||||
canGenerateTextReply := shouldGenerateNonMutatingTextDirective(semantic, routePlan, helpPath, creativeRequest) && planningReply == deterministicReply
|
||||
if (planningReply == "" && needsCognition && semantic.Interpretation.SpeechAct == interaction.SpeechActQuestion || canGenerateTextReply) && !hasChatRoute(routePlan, chatRouteResearch) && !creativeRequest {
|
||||
answerCtx, cancelAnswer := context.WithTimeout(r.Context(), 12*time.Second)
|
||||
answer, answerErr := cognitiveClient.AnswerStableKnowledge(answerCtx, session, effectiveTaskMessage, personalMemory.ContextText(), cognitive.TaskMeaning{
|
||||
answer, answerErr := cognitiveClient.AnswerStableKnowledge(answerCtx, session, effectiveTaskMessage, gen2Context.Text, cognitive.TaskMeaning{
|
||||
SpeechAct: string(semantic.Interpretation.SpeechAct), CapabilityHints: toCapabilityKinds(semantic.CapabilityHints), RequestedOutcome: semantic.Interpretation.RequestedOutcome, InformationRequestKind: semantic.InformationRequestKind, ConfidenceMillis: semantic.Interpretation.ConfidenceMillis,
|
||||
})
|
||||
cancelAnswer()
|
||||
@@ -992,7 +992,7 @@ func main() {
|
||||
}
|
||||
if strings.TrimSpace(planningReply) != "" {
|
||||
reviewContext, cancelReview := context.WithTimeout(r.Context(), 12*time.Second)
|
||||
reviewedReply, reviewErr := cognitiveClient.ReviewResponse(reviewContext, session, utterance.Content, planningReply, personalMemory.ContextText(), cognitive.TaskMeaning{
|
||||
reviewedReply, reviewErr := cognitiveClient.ReviewResponse(reviewContext, session, utterance.Content, planningReply, gen2Context.Text, cognitive.TaskMeaning{
|
||||
SpeechAct: string(semantic.Interpretation.SpeechAct),
|
||||
CapabilityHints: toCapabilityKinds(semantic.CapabilityHints),
|
||||
RequestedOutcome: semantic.Interpretation.RequestedOutcome,
|
||||
|
||||
@@ -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,41 @@
|
||||
package capability
|
||||
|
||||
type IntelligencePath string
|
||||
|
||||
const (
|
||||
PathRule IntelligencePath = "RULE"
|
||||
PathReflex IntelligencePath = "REFLEX"
|
||||
PathSkill IntelligencePath = "SKILL"
|
||||
PathSmallLocal IntelligencePath = "SMALL_LOCAL"
|
||||
PathStrongLocal IntelligencePath = "STRONG_LOCAL"
|
||||
PathExternal IntelligencePath = "EXTERNAL"
|
||||
PathResearch IntelligencePath = "RESEARCH"
|
||||
PathTeam IntelligencePath = "TEAM"
|
||||
)
|
||||
|
||||
type StrategyRequest struct {
|
||||
RequiredQuality int64
|
||||
PreferLowLatency bool
|
||||
CostBudgetMicros int64
|
||||
RiskClass string
|
||||
FreshnessRequired bool
|
||||
CostOfError int64
|
||||
}
|
||||
type StrategyDecision struct {
|
||||
Path IntelligencePath
|
||||
Reason string
|
||||
Escalate bool
|
||||
}
|
||||
|
||||
func (r StrategyRequest) Select() StrategyDecision {
|
||||
if r.RiskClass == "HIGH" || r.CostOfError >= 800 {
|
||||
return StrategyDecision{Path: PathStrongLocal, Reason: "high consequence requires deeper reasoning", Escalate: true}
|
||||
}
|
||||
if r.RequiredQuality <= 500 && r.CostBudgetMicros > 0 {
|
||||
return StrategyDecision{Path: PathRule, Reason: "bounded low-risk path"}
|
||||
}
|
||||
if r.PreferLowLatency {
|
||||
return StrategyDecision{Path: PathReflex, Reason: "latency preference with later escalation"}
|
||||
}
|
||||
return StrategyDecision{Path: PathSkill, Reason: "validated reusable strategy"}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package capability
|
||||
|
||||
type ReflexID string
|
||||
type ReflexLifecycle string
|
||||
type ReflexKind string
|
||||
|
||||
const (
|
||||
ReflexCandidate ReflexLifecycle = "CANDIDATE"
|
||||
ReflexValidating ReflexLifecycle = "VALIDATING"
|
||||
ReflexActive ReflexLifecycle = "ACTIVE"
|
||||
ReflexDegraded ReflexLifecycle = "DEGRADED"
|
||||
ReflexStale ReflexLifecycle = "STALE"
|
||||
ReflexSuspended ReflexLifecycle = "SUSPENDED"
|
||||
ReflexRetired ReflexLifecycle = "RETIRED"
|
||||
ReflexDeterministicCode ReflexKind = "DETERMINISTIC_CODE"
|
||||
ReflexRule ReflexKind = "RULE"
|
||||
ReflexWorkflow ReflexKind = "WORKFLOW"
|
||||
ReflexQueryTemplate ReflexKind = "QUERY_TEMPLATE"
|
||||
ReflexSmallModelChain ReflexKind = "SMALL_MODEL_CHAIN"
|
||||
ReflexBoundedAdapter ReflexKind = "BOUNDED_ADAPTER_OPERATION"
|
||||
)
|
||||
|
||||
type ShadowPolicy struct {
|
||||
Enabled bool
|
||||
SampleRateMillis int64
|
||||
ComparatorRef string
|
||||
MaxShadowCostMicros *int64
|
||||
EligibleErrorCostClasses []string
|
||||
}
|
||||
type RevalidationPolicy struct {
|
||||
MaxAgeMillis *int64
|
||||
RevalidateOnDependencyRevisionChange bool
|
||||
RevalidateOnWorldVersionChange bool
|
||||
RevalidateAfterFailureCount *int64
|
||||
RevalidateAfterCorrectionCount *int64
|
||||
SampleAuditRateMillis *int64
|
||||
}
|
||||
type Reflex struct {
|
||||
ID ReflexID
|
||||
PrincipalID string
|
||||
SourceSkillRef SkillID
|
||||
CreatedAt int64
|
||||
}
|
||||
type ReflexRevision struct {
|
||||
ReflexID ReflexID
|
||||
Revision int64
|
||||
SourceSkillRevision int64
|
||||
Kind ReflexKind
|
||||
Applicability ApplicabilitySpec
|
||||
ImplementationRef string
|
||||
ImplementationVersion string
|
||||
ArtifactDigest string
|
||||
DependencyRefs []string
|
||||
ValidationEvidenceRefs []SkillEvidenceRef
|
||||
KnownFailureExperienceRefs []SkillEvidenceRef
|
||||
Shadow ShadowPolicy
|
||||
Revalidation RevalidationPolicy
|
||||
LastValidatedAt int64
|
||||
Lifecycle ReflexLifecycle
|
||||
RecordedAt int64
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package capability
|
||||
|
||||
type SkillID string
|
||||
type SkillRevision struct {
|
||||
SkillID SkillID
|
||||
Revision int64
|
||||
Description string
|
||||
Applicability ApplicabilitySpec
|
||||
ImplementationRef string
|
||||
ImplementationVersion string
|
||||
DependencyRefs []string
|
||||
SupportingExperienceRefs []SkillEvidenceRef
|
||||
KnownFailureExperienceRefs []SkillEvidenceRef
|
||||
ValidationEvidenceRefs []SkillEvidenceRef
|
||||
QualityAssessmentRefs []string
|
||||
EnvironmentVersionConstraints []string
|
||||
LastValidatedAt int64
|
||||
Lifecycle SkillLifecycleStatus
|
||||
SupersedesRevision int64
|
||||
RecordedAt int64
|
||||
}
|
||||
type ApplicabilitySpec struct {
|
||||
RequiredContextBindings []string
|
||||
PreferredContextBindings []string
|
||||
ExcludedContextBindings []string
|
||||
RequiredWorldKinds []string
|
||||
VersionConstraints []string
|
||||
InputConditions []string
|
||||
MinimumEvidenceFreshness string
|
||||
}
|
||||
type Skill struct {
|
||||
ID SkillID
|
||||
PrincipalID string
|
||||
Name string
|
||||
CreatedAt int64
|
||||
}
|
||||
@@ -11,14 +11,24 @@ import (
|
||||
var ErrInvalidContextBudget = errors.New("context budget must be positive")
|
||||
|
||||
type ContextCandidate struct {
|
||||
Excerpt ContextExcerpt
|
||||
Relevance int
|
||||
Excerpt ContextExcerpt
|
||||
Relevance int
|
||||
Lane string
|
||||
ContextScopeRef string
|
||||
FreshnessState string
|
||||
Negative bool
|
||||
}
|
||||
|
||||
type ContextCompileInput struct {
|
||||
Candidates []ContextCandidate
|
||||
DataPolicy capability.DataPolicy
|
||||
MaxBytes int
|
||||
Candidates []ContextCandidate
|
||||
DataPolicy capability.DataPolicy
|
||||
MaxBytes int
|
||||
TaskRef string
|
||||
FocusFrameRef string
|
||||
ContextScopeRef string
|
||||
FreshnessRequirement string
|
||||
RiskClass string
|
||||
TokenBudget int
|
||||
}
|
||||
|
||||
type ContextOmission struct {
|
||||
@@ -30,6 +40,24 @@ type ContextBundle struct {
|
||||
Excerpts []ContextExcerpt
|
||||
Omissions []ContextOmission
|
||||
Bytes int
|
||||
Trace ContextAssemblyTrace
|
||||
}
|
||||
|
||||
type ContextAssemblyTrace struct {
|
||||
Included []ContextExcerptID
|
||||
Excluded []ContextOmission
|
||||
Coverage string
|
||||
CompilerVersion string
|
||||
}
|
||||
|
||||
type IterativeRetrievalRequest struct {
|
||||
Query string
|
||||
RemainingBytes int
|
||||
Pass int
|
||||
}
|
||||
type IterativeRetrievalResponse struct {
|
||||
Candidates []ContextCandidate
|
||||
Exhausted bool
|
||||
}
|
||||
|
||||
// CompileContext deterministically selects permitted, relevant excerpts for a
|
||||
@@ -54,6 +82,10 @@ func CompileContext(input ContextCompileInput) (ContextBundle, error) {
|
||||
continue
|
||||
}
|
||||
seen[excerpt.ID] = struct{}{}
|
||||
if input.ContextScopeRef != "" && candidate.ContextScopeRef != input.ContextScopeRef {
|
||||
bundle.Omissions = append(bundle.Omissions, ContextOmission{ID: excerpt.ID, Reason: "context_scope"})
|
||||
continue
|
||||
}
|
||||
reason := permittedContextReason(excerpt, input.DataPolicy)
|
||||
if reason != "" {
|
||||
bundle.Omissions = append(bundle.Omissions, ContextOmission{ID: excerpt.ID, Reason: reason})
|
||||
@@ -70,7 +102,11 @@ func CompileContext(input ContextCompileInput) (ContextBundle, error) {
|
||||
}
|
||||
bundle.Excerpts = append(bundle.Excerpts, excerpt)
|
||||
bundle.Bytes += bytes
|
||||
bundle.Trace.Included = append(bundle.Trace.Included, excerpt.ID)
|
||||
}
|
||||
bundle.Trace.Excluded = append([]ContextOmission(nil), bundle.Omissions...)
|
||||
bundle.Trace.CompilerVersion = "context-compiler-v2-additive"
|
||||
bundle.Trace.Coverage = "BOUNDED"
|
||||
return bundle, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package cognitive_test
|
||||
|
||||
import (
|
||||
"git.cin.su/m/Assistant/contracts/capability"
|
||||
"git.cin.su/m/Assistant/contracts/cognitive"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestContextCompilerV2TraceAndBudgetRemainDeterministic(t *testing.T) {
|
||||
b, err := cognitive.CompileContext(cognitive.ContextCompileInput{MaxBytes: 5, DataPolicy: capability.DataPolicyLocalOnly, TaskRef: "task", FocusFrameRef: "frame", ContextScopeRef: "company-a", Candidates: []cognitive.ContextCandidate{{Excerpt: cognitive.ContextExcerpt{ID: "a", Text: "123", Sensitivity: cognitive.SensitivityPrivateAllowed}, ContextScopeRef: "company-a", Relevance: 10}, {Excerpt: cognitive.ContextExcerpt{ID: "b", Text: "123456", Sensitivity: cognitive.SensitivityPrivateAllowed}, ContextScopeRef: "company-b", Relevance: 100}}})
|
||||
if err != nil || len(b.Excerpts) != 1 || len(b.Trace.Excluded) != 1 {
|
||||
t.Fatalf("bundle=%#v err=%v", b, err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package commit
|
||||
|
||||
type ExecutorResult string
|
||||
type AmbiguityState string
|
||||
|
||||
const (
|
||||
ExecutorAccepted ExecutorResult = "ACCEPTED"
|
||||
ExecutorReportedSuccess ExecutorResult = "REPORTED_SUCCESS"
|
||||
ExecutorReportedFailure ExecutorResult = "REPORTED_FAILURE"
|
||||
ExecutorNoResponse ExecutorResult = "NO_RESPONSE"
|
||||
ExecutorAmbiguous ExecutorResult = "AMBIGUOUS"
|
||||
)
|
||||
|
||||
type ExecutionReceipt struct {
|
||||
ID string
|
||||
ActionAttemptRef ActionAttemptID
|
||||
ExecutorImplementationRef string
|
||||
ExternalOperationRef string
|
||||
ExternalRequestID string
|
||||
RequestDigest string
|
||||
ResponseDigest string
|
||||
DispatchAtUnixMillis int64
|
||||
CompletedAtUnixMillis *int64
|
||||
ExecutorResult ExecutorResult
|
||||
Ambiguity AmbiguityState
|
||||
ReconciliationKey string
|
||||
RawArtifactRef string
|
||||
}
|
||||
|
||||
func (r ExecutionReceipt) Valid() bool {
|
||||
return r.ID != "" && r.ActionAttemptRef != "" && r.ExecutorImplementationRef != "" && r.RequestDigest != "" && r.ExecutorResult != "" && r.ReconciliationKey != "" && r.DispatchAtUnixMillis > 0
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.cin.su/m/Assistant/contracts/secrets"
|
||||
"git.cin.su/m/Assistant/platform/ids"
|
||||
)
|
||||
|
||||
type SettingDefinitionID ids.StableID
|
||||
type SettingAssignmentID ids.StableID
|
||||
type ConfigurationRevision ids.Revision
|
||||
type ValueType string
|
||||
type ResolutionMode string
|
||||
type SettingLifecycle string
|
||||
type SettingSource string
|
||||
|
||||
const (
|
||||
ValueString ValueType = "STRING"
|
||||
ValueInteger ValueType = "INTEGER"
|
||||
ValueBoolean ValueType = "BOOLEAN"
|
||||
ValueSecretRef ValueType = "SECRET_REF"
|
||||
ResolutionMostSpecific ResolutionMode = "MOST_SPECIFIC_WINS"
|
||||
ResolutionFirstHuman ResolutionMode = "FIRST_EXPLICIT_HUMAN_WINS"
|
||||
ResolutionMergeList ResolutionMode = "MERGE_LIST"
|
||||
SettingActive SettingLifecycle = "ACTIVE"
|
||||
SettingDeprecated SettingLifecycle = "DEPRECATED"
|
||||
SettingRetired SettingLifecycle = "RETIRED"
|
||||
SourceHumanDirective SettingSource = "HUMAN_DIRECTIVE"
|
||||
SourceMigrated SettingSource = "MIGRATED_CONFIG"
|
||||
SourceSkillDefault SettingSource = "SKILL_DEFAULT"
|
||||
SourceSystemDefault SettingSource = "SYSTEM_DEFAULT"
|
||||
SourceGovernedChange SettingSource = "GOVERNED_CHANGE"
|
||||
)
|
||||
|
||||
type SettingDefinition struct {
|
||||
ID SettingDefinitionID
|
||||
OwnerNamespace string
|
||||
StableKey string
|
||||
Revision ConfigurationRevision
|
||||
ValueType ValueType
|
||||
DefaultValue string
|
||||
Sensitivity string
|
||||
Lifecycle SettingLifecycle
|
||||
RecordedAtUnixMillis int64
|
||||
}
|
||||
type ScopeSelector struct {
|
||||
PrincipalRef string
|
||||
RequiredContextBindings []string
|
||||
ActivityRef string
|
||||
SkillRef string
|
||||
TaskRef string
|
||||
SessionRef string
|
||||
TemporaryOverride bool
|
||||
}
|
||||
type SettingAssignment struct {
|
||||
ID SettingAssignmentID
|
||||
PrincipalID string
|
||||
DefinitionRef string
|
||||
DefinitionRevision ConfigurationRevision
|
||||
Revision ConfigurationRevision
|
||||
Selector ScopeSelector
|
||||
TypedValue string
|
||||
SecretRef *secrets.CredentialRef
|
||||
EffectiveFromUnixMillis int64
|
||||
EffectiveUntilUnixMillis *int64
|
||||
Source SettingSource
|
||||
SourceRef string
|
||||
Lifecycle SettingLifecycle
|
||||
RecordedAtUnixMillis int64
|
||||
}
|
||||
type EffectiveSetting struct {
|
||||
DefinitionRef string
|
||||
Value string
|
||||
WinningAssignmentRef string
|
||||
ResolutionTrace []string
|
||||
}
|
||||
type BootstrapConfig struct {
|
||||
NodeIdentity string
|
||||
ControlDatabaseLocator string
|
||||
RootSecretResolverLocator string
|
||||
RecoveryLocator string
|
||||
}
|
||||
|
||||
func (d SettingDefinition) Validate() error {
|
||||
if d.ID == "" || d.OwnerNamespace == "" || d.StableKey == "" || !ids.Revision(d.Revision).Valid() || d.ValueType == "" || d.Lifecycle == "" || d.RecordedAtUnixMillis < 1 {
|
||||
return fmt.Errorf("invalid setting definition")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (a SettingAssignment) Validate() error {
|
||||
if a.ID == "" || a.PrincipalID == "" || a.DefinitionRef == "" || !ids.Revision(a.Revision).Valid() || a.Source == "" || a.Lifecycle == "" || a.RecordedAtUnixMillis < 1 {
|
||||
return fmt.Errorf("invalid setting assignment")
|
||||
}
|
||||
if a.SecretRef != nil && a.TypedValue != "" {
|
||||
return fmt.Errorf("secret assignment must not contain typed value")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package epistemics
|
||||
|
||||
type WorldOutcomeState string
|
||||
|
||||
const (
|
||||
OutcomeVerifiedSuccess WorldOutcomeState = "VERIFIED_SUCCESS"
|
||||
OutcomeVerifiedPartial WorldOutcomeState = "VERIFIED_PARTIAL"
|
||||
OutcomeVerifiedFailure WorldOutcomeState = "VERIFIED_FAILURE"
|
||||
OutcomeUnverified WorldOutcomeState = "UNVERIFIED"
|
||||
OutcomeUnknownState WorldOutcomeState = "UNKNOWN"
|
||||
OutcomeConflicted WorldOutcomeState = "CONFLICTED"
|
||||
)
|
||||
|
||||
type WorldOutcomeAssessment struct {
|
||||
ID string
|
||||
PrincipalID string
|
||||
ActionAttemptRef string
|
||||
ExecutionReceiptRefs []string
|
||||
ExpectedEffectRef string
|
||||
ObservationRefs []ObservationID
|
||||
ClaimRefs []ClaimID
|
||||
State WorldOutcomeState
|
||||
ConfidenceMillis int64
|
||||
EvidenceRefs []EvidenceRef
|
||||
AssessedAt int64
|
||||
}
|
||||
|
||||
func (a WorldOutcomeAssessment) Valid() bool {
|
||||
return a.ID != "" && a.PrincipalID != "" && a.ActionAttemptRef != "" && a.State != "" && a.ConfidenceMillis >= 0 && a.ConfidenceMillis <= 1000 && a.AssessedAt > 0
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package self
|
||||
|
||||
type BenchmarkCaseRef string
|
||||
type PersonalBenchmark struct {
|
||||
ID string
|
||||
PrincipalID string
|
||||
ApprovedCaseRefs []BenchmarkCaseRef
|
||||
GoalProfile []string
|
||||
PreferenceEvidenceRefs []SemanticReference
|
||||
RecordedAt int64
|
||||
}
|
||||
type BenchmarkEvaluation struct {
|
||||
CaseRef BenchmarkCaseRef
|
||||
Path string
|
||||
QualityMillis int64
|
||||
ReliabilityMillis int64
|
||||
LatencyMillis int64
|
||||
CostMicros int64
|
||||
CorrectionCount int64
|
||||
EvidenceRefs []SemanticReference
|
||||
}
|
||||
|
||||
func (e BenchmarkEvaluation) Valid() bool {
|
||||
return e.CaseRef != "" && len(e.EvidenceRefs) > 0 && e.QualityMillis >= 0 && e.ReliabilityMillis >= 0 && e.CorrectionCount >= 0
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package self
|
||||
|
||||
import "fmt"
|
||||
|
||||
type AssessmentID string
|
||||
type LearningLedgerEntryID string
|
||||
type AssessmentState string
|
||||
|
||||
const (
|
||||
AssessmentCandidate AssessmentState = "CANDIDATE"
|
||||
AssessmentConfirmed AssessmentState = "CONFIRMED"
|
||||
AssessmentMonitoring AssessmentState = "MONITORING"
|
||||
AssessmentResolved AssessmentState = "RESOLVED"
|
||||
)
|
||||
|
||||
type CompetenceAssessment struct {
|
||||
ID AssessmentID
|
||||
PrincipalID string
|
||||
SubjectRef SemanticReference
|
||||
Revision uint64
|
||||
ContextMatcher []string
|
||||
QualityMillis int64
|
||||
ReliabilityMillis int64
|
||||
ConfidenceMillis int64
|
||||
EvidenceRefs []SemanticReference
|
||||
LastValidatedAt int64
|
||||
AssessedAt int64
|
||||
SupersedesRef *SemanticReference
|
||||
}
|
||||
type WeaknessPattern struct {
|
||||
ID AssessmentID
|
||||
PrincipalID string
|
||||
Revision uint64
|
||||
PatternKey string
|
||||
ContextMatcher []string
|
||||
FailureMode string
|
||||
DetectionEvidenceRefs []SemanticReference
|
||||
State AssessmentState
|
||||
RecordedAt int64
|
||||
}
|
||||
type DependencyAssessment struct {
|
||||
ID AssessmentID
|
||||
SubjectRef SemanticReference
|
||||
DependencyRef SemanticReference
|
||||
ImpactClass string
|
||||
CurrentEffect string
|
||||
EvidenceRefs []SemanticReference
|
||||
AssessedAt int64
|
||||
}
|
||||
type ImprovementNeed struct {
|
||||
ID AssessmentID
|
||||
PrincipalID string
|
||||
SubjectRef SemanticReference
|
||||
ProblemSummary string
|
||||
EvidenceRefs []SemanticReference
|
||||
ExpectedBenefit string
|
||||
Priority int
|
||||
State string
|
||||
CreatedAt int64
|
||||
}
|
||||
type LearningLedgerEntry struct {
|
||||
ID LearningLedgerEntryID
|
||||
PrincipalID string
|
||||
ImprovementNeedRef *SemanticReference
|
||||
ObservedProblem string
|
||||
EvidenceRefs []SemanticReference
|
||||
Diagnosis string
|
||||
Hypothesis string
|
||||
ProposedChangeRef SemanticReference
|
||||
ExpectedImprovement string
|
||||
ActualEvaluationRefs []SemanticReference
|
||||
DevelopmentGateRef *SemanticReference
|
||||
BeforeVersionRefs []SemanticReference
|
||||
AfterVersionRefs []SemanticReference
|
||||
Decision string
|
||||
SideEffects []string
|
||||
RollbackRef *SemanticReference
|
||||
RecordedAt int64
|
||||
}
|
||||
|
||||
func (a CompetenceAssessment) Validate() error {
|
||||
if a.ID == "" || a.PrincipalID == "" || !a.SubjectRef.Valid() || a.Revision < 1 || a.ConfidenceMillis < 0 || a.ConfidenceMillis > 1000 || len(a.EvidenceRefs) == 0 || a.AssessedAt < 1 {
|
||||
return fmt.Errorf("competence requires evidence")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (l LearningLedgerEntry) Validate() error {
|
||||
if l.ID == "" || l.PrincipalID == "" || l.ObservedProblem == "" || len(l.EvidenceRefs) == 0 || l.Decision == "" || l.RecordedAt < 1 {
|
||||
return fmt.Errorf("learning ledger entry is incomplete")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package work
|
||||
|
||||
type ConsequenceAssessment struct {
|
||||
ID string
|
||||
TargetRefs []string
|
||||
Impact int64
|
||||
Reversibility int64
|
||||
Uncertainty int64
|
||||
Scope int64
|
||||
Recoverability int64
|
||||
CostOfError int64
|
||||
ExpectedConsequences []string
|
||||
MitigationOptions []string
|
||||
RequiresDryRun bool
|
||||
RequiresBackup bool
|
||||
RecommendedConfirmation string
|
||||
OwnerAccepted bool
|
||||
EvidenceRefs []EvidenceRef
|
||||
RecordedAtUnixMillis int64
|
||||
}
|
||||
|
||||
func (a ConsequenceAssessment) Valid() bool {
|
||||
return a.ID != "" && len(a.TargetRefs) > 0 && a.Impact >= 0 && a.Impact <= 1000 && a.Reversibility >= 0 && a.Reversibility <= 1000 && a.Uncertainty >= 0 && a.Uncertainty <= 1000 && a.Recoverability >= 0 && a.Recoverability <= 1000 && a.RecordedAtUnixMillis > 0
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package work
|
||||
|
||||
type LongRunningWorkID string
|
||||
type LongRunningState string
|
||||
|
||||
const (
|
||||
LongRunningProposed LongRunningState = "PROPOSED"
|
||||
LongRunningRunning LongRunningState = "RUNNING"
|
||||
LongRunningPaused LongRunningState = "PAUSED"
|
||||
LongRunningBlocked LongRunningState = "BLOCKED"
|
||||
LongRunningCompleted LongRunningState = "COMPLETED"
|
||||
LongRunningExhausted LongRunningState = "EXHAUSTED"
|
||||
LongRunningCancelled LongRunningState = "CANCELLED"
|
||||
)
|
||||
|
||||
type Investigation struct {
|
||||
ID LongRunningWorkID
|
||||
Objective string
|
||||
HypothesisRefs []EvidenceRef
|
||||
AttemptRefs []AgentRunID
|
||||
FindingRefs []EvidenceRef
|
||||
Blockers []string
|
||||
CheckpointRefs []AgentCheckpointID
|
||||
NextStep string
|
||||
State LongRunningState
|
||||
Revision int64
|
||||
TimeBudgetMillis int64
|
||||
CostBudgetMicros int64
|
||||
MaxAttempts int
|
||||
RecordedAtUnixMillis int64
|
||||
}
|
||||
|
||||
func (w Investigation) Valid() bool {
|
||||
return w.ID != "" && w.Objective != "" && w.State != "" && w.Revision > 0 && w.TimeBudgetMillis >= 0 && w.CostBudgetMicros >= 0 && w.MaxAttempts >= 0 && w.RecordedAtUnixMillis > 0
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package work
|
||||
|
||||
type PerspectiveID string
|
||||
type PerspectiveSpec struct {
|
||||
ID PerspectiveID
|
||||
ObjectiveLens string
|
||||
RetrievalProfileRef string
|
||||
EvaluationCriteria []string
|
||||
CapabilityRequirements []string
|
||||
ExpectedOutputShape string
|
||||
Critic bool
|
||||
}
|
||||
type SpecialistAssignment struct {
|
||||
Perspective PerspectiveSpec
|
||||
SubtaskRef string
|
||||
EvidenceRefs []EvidenceRef
|
||||
}
|
||||
type TeamDecision struct {
|
||||
UseTeam bool
|
||||
Reason string
|
||||
Assignments []SpecialistAssignment
|
||||
}
|
||||
|
||||
func (p PerspectiveSpec) Valid() bool {
|
||||
return p.ID != "" && p.ObjectiveLens != "" && len(p.EvaluationCriteria) > 0 && p.ExpectedOutputShape != ""
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
BEGIN;
|
||||
SET ROLE configuration_role;
|
||||
CREATE TABLE IF NOT EXISTS configuration.setting_definitions (setting_definition_id TEXT PRIMARY KEY, owner_namespace TEXT NOT NULL, stable_key TEXT NOT NULL, revision BIGINT NOT NULL CHECK(revision>0), value_type TEXT NOT NULL, default_value TEXT, sensitivity TEXT NOT NULL, lifecycle TEXT NOT NULL, recorded_at_unix_millis BIGINT NOT NULL);
|
||||
CREATE TABLE IF NOT EXISTS configuration.setting_assignments (setting_assignment_id TEXT PRIMARY KEY, principal_id TEXT NOT NULL, definition_ref JSONB NOT NULL, revision BIGINT NOT NULL CHECK(revision>0), selector JSONB NOT NULL, typed_value TEXT, secret_ref TEXT, effective_from_unix_millis BIGINT NOT NULL, effective_until_unix_millis BIGINT, source TEXT NOT NULL, source_ref TEXT NOT NULL, lifecycle TEXT NOT NULL, recorded_at_unix_millis BIGINT NOT NULL);
|
||||
GRANT SELECT, INSERT, UPDATE ON configuration.setting_definitions, configuration.setting_assignments TO configuration_role;
|
||||
RESET ROLE;
|
||||
COMMIT;
|
||||
@@ -0,0 +1,7 @@
|
||||
BEGIN;
|
||||
SET ROLE self_role;
|
||||
CREATE TABLE IF NOT EXISTS self.competence_assessments (assessment_id TEXT PRIMARY KEY, principal_id TEXT NOT NULL, subject_ref JSONB NOT NULL, revision BIGINT NOT NULL CHECK(revision>0), context_matcher JSONB NOT NULL, confidence_millis BIGINT NOT NULL, evidence_refs JSONB NOT NULL, assessed_at_unix_millis BIGINT NOT NULL);
|
||||
CREATE TABLE IF NOT EXISTS self.learning_ledger (entry_id TEXT PRIMARY KEY, principal_id TEXT NOT NULL, observed_problem TEXT NOT NULL, evidence_refs JSONB NOT NULL, diagnosis TEXT NOT NULL, hypothesis TEXT NOT NULL, decision TEXT NOT NULL, recorded_at_unix_millis BIGINT NOT NULL);
|
||||
GRANT SELECT, INSERT, UPDATE ON self.competence_assessments, self.learning_ledger TO self_role;
|
||||
RESET ROLE;
|
||||
COMMIT;
|
||||
@@ -1 +1 @@
|
||||
{"task_file":"dev/tasks/GEN2-008-promote-episode-and-experience-v2-including-negative-experience.json","task_id":"GEN2-008","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,15 @@
|
||||
package domain_test
|
||||
|
||||
import (
|
||||
"git.cin.su/m/Assistant/contracts/capability"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStrategyUsesRiskAndCostSignals(t *testing.T) {
|
||||
if got := (capability.StrategyRequest{RequiredQuality: 400, CostBudgetMicros: 10}).Select().Path; got != capability.PathRule {
|
||||
t.Fatal(got)
|
||||
}
|
||||
if got := (capability.StrategyRequest{RiskClass: "HIGH", CostOfError: 900}).Select(); got.Path != capability.PathStrongLocal || !got.Escalate {
|
||||
t.Fatalf("%#v", got)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.cin.su/m/Assistant/contracts/capability"
|
||||
)
|
||||
|
||||
func ValidateReflexRevision(v capability.ReflexRevision) error {
|
||||
if v.ReflexID == "" || v.SourceSkillRevision < 1 || v.Kind == "" || v.ImplementationRef == "" || v.Lifecycle == "" || v.RecordedAt < 1 {
|
||||
return fmt.Errorf("invalid reflex revision")
|
||||
}
|
||||
if v.Lifecycle == capability.ReflexActive && len(v.ValidationEvidenceRefs) == 0 {
|
||||
return fmt.Errorf("active reflex requires evidence")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func ReflexFallback(d capability.FastPathDecision) string {
|
||||
if d.Decision == capability.FastPathApplied {
|
||||
return "reflex"
|
||||
}
|
||||
return "skill->reasoning"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package domain_test
|
||||
|
||||
import (
|
||||
"git.cin.su/m/Assistant/contracts/capability"
|
||||
"git.cin.su/m/Assistant/modules/capability/domain"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestReflexActiveRequiresEvidenceAndFallbacks(t *testing.T) {
|
||||
v := capability.ReflexRevision{ReflexID: "r", SourceSkillRevision: 1, Kind: capability.ReflexRule, ImplementationRef: "rule", Lifecycle: capability.ReflexActive, RecordedAt: 1}
|
||||
if domain.ValidateReflexRevision(v) == nil {
|
||||
t.Fatal("active reflex without evidence")
|
||||
}
|
||||
v.ValidationEvidenceRefs = []capability.SkillEvidenceRef{"eval"}
|
||||
if err := domain.ValidateReflexRevision(v); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if domain.ReflexFallback(capability.FastPathDecision{Decision: capability.FastPathEscalate}) != "skill->reasoning" {
|
||||
t.Fatal("missing escalation")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.cin.su/m/Assistant/contracts/capability"
|
||||
)
|
||||
|
||||
func ValidateSkillRevision(value capability.SkillRevision) error {
|
||||
if value.SkillID == "" || value.Revision < 1 || value.ImplementationRef == "" || value.Lifecycle == "" || value.RecordedAt < 1 {
|
||||
return fmt.Errorf("invalid skill revision")
|
||||
}
|
||||
if value.Lifecycle == capability.SkillValidated && len(value.ValidationEvidenceRefs) == 0 {
|
||||
return fmt.Errorf("validated skill requires evidence")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
# configuration
|
||||
|
||||
Configuration owns typed, scoped, versioned settings. ENV is limited to
|
||||
bootstrap primitives; secret values are never configuration values.
|
||||
@@ -0,0 +1,11 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"git.cin.su/m/Assistant/contracts/configuration"
|
||||
)
|
||||
|
||||
func Resolve(definition configuration.SettingDefinition, assignments []configuration.SettingAssignment, selector configuration.ScopeSelector) (configuration.EffectiveSetting,error){if err:=definition.Validate();err!=nil{return configuration.EffectiveSetting{},err}; var matches []configuration.SettingAssignment;for _,a:=range assignments{if err:=a.Validate();err!=nil{return configuration.EffectiveSetting{},err};if a.DefinitionRef==string(definition.ID)&&a.Lifecycle==configuration.SettingActive&&a.Selector.PrincipalRef==selector.PrincipalRef&&a.Selector.SkillRef==selector.SkillRef{matches=append(matches,a)}};if len(matches)==0{return configuration.EffectiveSetting{DefinitionRef:string(definition.ID),Value:definition.DefaultValue,ResolutionTrace:[]string{"system-default"}},nil};sort.SliceStable(matches,func(i,j int)bool{return specificity(matches[i].Selector)>specificity(matches[j].Selector)});if len(matches)>1&&specificity(matches[0].Selector)==specificity(matches[1].Selector){return configuration.EffectiveSetting{},fmt.Errorf("configuration conflict")};return configuration.EffectiveSetting{DefinitionRef:string(definition.ID),Value:matches[0].TypedValue,WinningAssignmentRef:string(matches[0].ID),ResolutionTrace:[]string{"specificity-selected"}},nil}
|
||||
func specificity(s configuration.ScopeSelector)int{return len(s.RequiredContextBindings)+boolInt(s.SkillRef!="")+boolInt(s.TaskRef!="")+boolInt(s.SessionRef!="")+boolInt(s.TemporaryOverride)}
|
||||
func boolInt(v bool)int{if v{return 1};return 0}
|
||||
@@ -0,0 +1,3 @@
|
||||
package domain_test
|
||||
import("testing"; "git.cin.su/m/Assistant/contracts/configuration"; "git.cin.su/m/Assistant/modules/configuration/domain")
|
||||
func TestConfigurationResolvesCompanyAndSkillScope(t *testing.T){d:=configuration.SettingDefinition{ID:"x",OwnerNamespace:"capability",StableKey:"endpoint",Revision:1,ValueType:configuration.ValueString,Lifecycle:configuration.SettingActive,RecordedAtUnixMillis:1};a:=configuration.SettingAssignment{ID:"a",PrincipalID:"company-a",DefinitionRef:"x",Revision:1,Selector:configuration.ScopeSelector{PrincipalRef:"company-a",SkillRef:"skill"},TypedValue:"a-value",Source:configuration.SourceHumanDirective,Lifecycle:configuration.SettingActive,RecordedAtUnixMillis:1};got,err:=domain.Resolve(d,[]configuration.SettingAssignment{a},configuration.ScopeSelector{PrincipalRef:"company-a",SkillRef:"skill"});if err!=nil||got.Value!="a-value"{t.Fatalf("got %#v err=%v",got,err)}}
|
||||
@@ -0,0 +1,19 @@
|
||||
package domain
|
||||
|
||||
import "git.cin.su/m/Assistant/contracts/interaction"
|
||||
|
||||
type ContextProjection struct {
|
||||
Text string
|
||||
Source string
|
||||
UsedPersonalMemoryFallback bool
|
||||
}
|
||||
|
||||
// BuildGen2Context is a read-side projection over canonical utterance history.
|
||||
// PersonalMemory remains a compatibility fallback and is never written here.
|
||||
func BuildGen2Context(history []interaction.HumanUtterance) ContextProjection {
|
||||
text := CompilePersonalMemory(history).ContextText()
|
||||
if text != "" {
|
||||
return ContextProjection{Text: text, Source: "retrieval:interaction-utterances"}
|
||||
}
|
||||
return ContextProjection{Text: text, Source: "personal-memory-v1-fallback", UsedPersonalMemoryFallback: true}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package domain_test
|
||||
|
||||
import (
|
||||
"git.cin.su/m/Assistant/contracts/interaction"
|
||||
"git.cin.su/m/Assistant/modules/interaction/domain"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGen2ContextUsesRetrievalProjectionAndKeepsV1Fallback(t *testing.T) {
|
||||
got := domain.BuildGen2Context([]interaction.HumanUtterance{{ID: "u", Content: "Я сейчас в Москве", ReceivedAtUnixMillis: 1}})
|
||||
if got.Source != "retrieval:interaction-utterances" || got.UsedPersonalMemoryFallback {
|
||||
t.Fatalf("got %#v", got)
|
||||
}
|
||||
empty := domain.BuildGen2Context(nil)
|
||||
if !empty.UsedPersonalMemoryFallback {
|
||||
t.Fatalf("fallback missing: %#v", empty)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package domain_test
|
||||
|
||||
import (
|
||||
selfcontract "git.cin.su/m/Assistant/contracts/self"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBenchmarkRequiresEvidenceAndDoesNotPromoteAlone(t *testing.T) {
|
||||
e := selfcontract.BenchmarkEvaluation{CaseRef: "case", QualityMillis: 900}
|
||||
if e.Valid() {
|
||||
t.Fatal("benchmark without evidence accepted")
|
||||
}
|
||||
e.EvidenceRefs = []selfcontract.SemanticReference{{OwnerNamespace: "epistemics", SemanticKind: "evaluation", StableID: "e"}}
|
||||
if !e.Valid() {
|
||||
t.Fatal("evidence-backed evaluation rejected")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"git.cin.su/m/Assistant/contracts/self"
|
||||
)
|
||||
|
||||
func ValidateCompetence(v self.CompetenceAssessment) error { return v.Validate() }
|
||||
func ValidateLearning(v self.LearningLedgerEntry) error { return v.Validate() }
|
||||
@@ -0,0 +1,18 @@
|
||||
package domain_test
|
||||
|
||||
import (
|
||||
selfcontract "git.cin.su/m/Assistant/contracts/self"
|
||||
"git.cin.su/m/Assistant/modules/self/domain"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCompetenceCannotBeSelfDeclaredWithoutEvidence(t *testing.T) {
|
||||
v := selfcontract.CompetenceAssessment{ID: "a", PrincipalID: "p", SubjectRef: selfcontract.SemanticReference{OwnerNamespace: "capability", SemanticKind: "skill", StableID: "s"}, Revision: 1, ConfidenceMillis: 1000, AssessedAt: 1}
|
||||
if domain.ValidateCompetence(v) == nil {
|
||||
t.Fatal("unsupported competence accepted")
|
||||
}
|
||||
v.EvidenceRefs = []selfcontract.SemanticReference{{OwnerNamespace: "epistemics", SemanticKind: "evaluation", StableID: "e"}}
|
||||
if err := domain.ValidateCompetence(v); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package domain
|
||||
|
||||
import "git.cin.su/m/Assistant/contracts/work"
|
||||
|
||||
func AssessConsequences(id string, target string, impact, reversibility, uncertainty, recoverability, cost int64, at int64) work.ConsequenceAssessment {
|
||||
a := work.ConsequenceAssessment{ID: id, TargetRefs: []string{target}, Impact: impact, Reversibility: reversibility, Uncertainty: uncertainty, Recoverability: recoverability, CostOfError: cost, RecordedAtUnixMillis: at}
|
||||
a.RequiresDryRun = impact >= 700 || reversibility >= 700
|
||||
a.RequiresBackup = reversibility >= 500
|
||||
a.RecommendedConfirmation = "STANDARD"
|
||||
if uncertainty*cost > 500000 {
|
||||
a.RecommendedConfirmation = "EXPLICIT_OWNER_CONFIRMATION"
|
||||
}
|
||||
return a
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package domain_test
|
||||
|
||||
import (
|
||||
"git.cin.su/m/Assistant/modules/work/domain"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConsequenceAdvisesMitigationWithoutCapabilityBlacklist(t *testing.T) {
|
||||
a := domain.AssessConsequences("a", "database:a", 800, 800, 900, 300, 900, 1)
|
||||
if !a.Valid() || !a.RequiresDryRun || !a.RequiresBackup || a.RecommendedConfirmation != "EXPLICIT_OWNER_CONFIRMATION" {
|
||||
t.Fatalf("%#v", a)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package domain
|
||||
|
||||
import "git.cin.su/m/Assistant/contracts/work"
|
||||
|
||||
func PauseInvestigation(value work.Investigation) work.Investigation {
|
||||
if value.Valid() {
|
||||
value.State = work.LongRunningPaused
|
||||
value.Revision++
|
||||
}
|
||||
return value
|
||||
}
|
||||
func ResumeInvestigation(value work.Investigation) work.Investigation {
|
||||
if value.Valid() && value.State == work.LongRunningPaused {
|
||||
value.State = work.LongRunningRunning
|
||||
value.Revision++
|
||||
}
|
||||
return value
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package domain_test
|
||||
|
||||
import (
|
||||
"git.cin.su/m/Assistant/contracts/work"
|
||||
"git.cin.su/m/Assistant/modules/work/domain"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInvestigationPauseResumeIsDurableStateTransition(t *testing.T) {
|
||||
w := work.Investigation{ID: "i", Objective: "diagnose", State: work.LongRunningRunning, Revision: 1, RecordedAtUnixMillis: 1}
|
||||
w = domain.PauseInvestigation(w)
|
||||
w = domain.ResumeInvestigation(w)
|
||||
if w.State != work.LongRunningRunning || w.Revision != 3 {
|
||||
t.Fatalf("%#v", w)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package domain
|
||||
|
||||
import "git.cin.su/m/Assistant/contracts/work"
|
||||
|
||||
func AssembleSpecialists(p work.PerspectiveSpec, subtasks []string) work.TeamDecision {
|
||||
if !p.Valid() {
|
||||
return work.TeamDecision{Reason: "invalid perspective"}
|
||||
}
|
||||
if len(subtasks) < 2 {
|
||||
return work.TeamDecision{Reason: "single reasoning path is sufficient"}
|
||||
}
|
||||
assignments := make([]work.SpecialistAssignment, 0, len(subtasks))
|
||||
for _, s := range subtasks {
|
||||
assignments = append(assignments, work.SpecialistAssignment{Perspective: p, SubtaskRef: s})
|
||||
}
|
||||
return work.TeamDecision{UseTeam: true, Reason: "independent subtasks justify bounded perspectives", Assignments: assignments}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package domain_test
|
||||
|
||||
import (
|
||||
"git.cin.su/m/Assistant/contracts/work"
|
||||
"git.cin.su/m/Assistant/modules/work/domain"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPerspectiveTeamIsBoundedByIndependentSubtasks(t *testing.T) {
|
||||
p := work.PerspectiveSpec{ID: "architect", ObjectiveLens: "architecture", EvaluationCriteria: []string{"correctness"}, ExpectedOutputShape: "finding"}
|
||||
if d := domain.AssembleSpecialists(p, []string{"a"}); d.UseTeam {
|
||||
t.Fatal("team for one subtask")
|
||||
}
|
||||
if d := domain.AssembleSpecialists(p, []string{"a", "b"}); !d.UseTeam || len(d.Assignments) != 2 {
|
||||
t.Fatalf("%#v", d)
|
||||
}
|
||||
}
|
||||
@@ -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,7 @@
|
||||
package secrets
|
||||
|
||||
import "git.cin.su/m/Assistant/contracts/configuration"
|
||||
|
||||
func ValidateBootstrap(value configuration.BootstrapConfig) bool {
|
||||
return value.NodeIdentity != "" && value.ControlDatabaseLocator != "" && value.RootSecretResolverLocator != ""
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package retrieval
|
||||
|
||||
import "sort"
|
||||
|
||||
type Lane string
|
||||
|
||||
const (
|
||||
LaneSemantic Lane = "SEMANTIC"
|
||||
LaneEntity Lane = "ENTITY"
|
||||
LaneTemporal Lane = "TEMPORAL"
|
||||
LaneGoal Lane = "GOAL"
|
||||
LanePositiveExperience Lane = "POSITIVE_EXPERIENCE"
|
||||
LaneNegativeExperience Lane = "NEGATIVE_EXPERIENCE"
|
||||
LaneContradiction Lane = "CONTRADICTION"
|
||||
LaneSkill Lane = "SKILL"
|
||||
)
|
||||
|
||||
// RetrievalDocument is disposable read-side projection data. SourceRef and
|
||||
// Owner preserve provenance; this type never becomes canonical meaning.
|
||||
type RetrievalDocument struct {
|
||||
ID string
|
||||
SourceRef string
|
||||
Owner string
|
||||
PrincipalID string
|
||||
ContextScopeRef string
|
||||
VersionRef string
|
||||
Lane Lane
|
||||
Text string
|
||||
Relevance int
|
||||
Freshness int
|
||||
Confidence int
|
||||
Salience int
|
||||
Cost int
|
||||
}
|
||||
|
||||
type Query struct {
|
||||
PrincipalID string
|
||||
ContextScopeRef string
|
||||
VersionRef string
|
||||
Lanes []Lane
|
||||
Limit int
|
||||
}
|
||||
|
||||
func FilterAndRank(documents []RetrievalDocument, query Query) []RetrievalDocument {
|
||||
filtered := make([]RetrievalDocument, 0, len(documents))
|
||||
for _, doc := range documents {
|
||||
if doc.PrincipalID != query.PrincipalID || (query.ContextScopeRef != "" && doc.ContextScopeRef != query.ContextScopeRef) || (query.VersionRef != "" && doc.VersionRef != query.VersionRef) || !containsLane(query.Lanes, doc.Lane) {
|
||||
continue
|
||||
}
|
||||
filtered = append(filtered, doc)
|
||||
}
|
||||
sort.SliceStable(filtered, func(i, j int) bool {
|
||||
left := filtered[i].Relevance + filtered[i].Freshness + filtered[i].Confidence + filtered[i].Salience - filtered[i].Cost
|
||||
right := filtered[j].Relevance + filtered[j].Freshness + filtered[j].Confidence + filtered[j].Salience - filtered[j].Cost
|
||||
if left != right {
|
||||
return left > right
|
||||
}
|
||||
return filtered[i].ID < filtered[j].ID
|
||||
})
|
||||
if query.Limit > 0 && len(filtered) > query.Limit {
|
||||
filtered = filtered[:query.Limit]
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func containsLane(lanes []Lane, lane Lane) bool {
|
||||
if len(lanes) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, v := range lanes {
|
||||
if v == lane {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type ProjectionBuilder interface {
|
||||
Build() ([]RetrievalDocument, error)
|
||||
}
|
||||
|
||||
func Rebuild(builders ...ProjectionBuilder) ([]RetrievalDocument, error) {
|
||||
var result []RetrievalDocument
|
||||
for _, builder := range builders {
|
||||
docs, err := builder.Build()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, docs...)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package retrieval_test
|
||||
|
||||
import (
|
||||
"git.cin.su/m/Assistant/runtime/retrieval"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestScopeAndVersionFilterBeforeRanking(t *testing.T) {
|
||||
docs := []retrieval.RetrievalDocument{{ID: "wrong-company", PrincipalID: "a", ContextScopeRef: "b", VersionRef: "v", Lane: retrieval.LaneSemantic, Relevance: 100}, {ID: "right", PrincipalID: "a", ContextScopeRef: "a", VersionRef: "v", Lane: retrieval.LaneNegativeExperience, Relevance: 1}, {ID: "wrong-version", PrincipalID: "a", ContextScopeRef: "a", VersionRef: "old", Lane: retrieval.LaneSemantic, Relevance: 100}}
|
||||
got := retrieval.FilterAndRank(docs, retrieval.Query{PrincipalID: "a", ContextScopeRef: "a", VersionRef: "v", Lanes: []retrieval.Lane{retrieval.LaneSemantic, retrieval.LaneNegativeExperience}, Limit: 10})
|
||||
if len(got) != 1 || got[0].ID != "right" {
|
||||
t.Fatalf("got %#v", got)
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package execution_outcome_test
|
||||
|
||||
import (
|
||||
"git.cin.su/m/Assistant/contracts/commit"
|
||||
"git.cin.su/m/Assistant/contracts/epistemics"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestReportedExecutionSuccessIsNotWorldVerification(t *testing.T) {
|
||||
r := commit.ExecutionReceipt{ID: "r", ActionAttemptRef: "a", ExecutorImplementationRef: "impl", RequestDigest: "d", ExecutorResult: commit.ExecutorReportedSuccess, ReconciliationKey: "k", DispatchAtUnixMillis: 1}
|
||||
if !r.Valid() {
|
||||
t.Fatal("receipt invalid")
|
||||
}
|
||||
o := epistemics.WorldOutcomeAssessment{ID: "o", PrincipalID: "p", ActionAttemptRef: "a", State: epistemics.OutcomeUnverified, ConfidenceMillis: 0, AssessedAt: 1}
|
||||
if !o.Valid() {
|
||||
t.Fatal("unverified assessment invalid")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user