Compare commits

...
Author SHA1 Message Date
m b282038949 GEN2-021: add independent supervisor lifeboat
CI / test (push) Failing after 27s
2026-08-29 11:30:49 +03:00
m 4de506a2af GEN2-020: separate execution receipts from world outcomes
CI / test (push) Failing after 26s
2026-08-29 11:30:05 +03:00
m 36272b9036 GEN2-019: add advisory consequence assessment
CI / test (push) Failing after 29s
2026-08-29 11:28:52 +03:00
m a779568622 GEN2-018: add bounded perspectives over Work Graph
CI / test (push) Failing after 27s
2026-08-29 11:28:05 +03:00
m 243a11490b GEN2-017: add durable long-running investigations
CI / test (push) Failing after 26s
2026-08-29 11:27:21 +03:00
m 26207d93ef GEN2-016: add intelligence strategy and benchmark evidence
CI / test (push) Failing after 26s
2026-08-29 11:16:07 +03:00
m 42871f2e47 GEN2-015: add evidence-backed SELF ledger
CI / test (push) Failing after 28s
2026-08-29 11:13:38 +03:00
m 6ea1d4b729 GEN2-014: add reflex lifecycle and escalation
CI / test (push) Failing after 28s
2026-08-29 11:12:42 +03:00
m c6d1ebf36f GEN2-013: add versioned Skill V2 contracts
CI / test (push) Failing after 27s
2026-08-29 11:11:50 +03:00
m 25d8d6d219 GEN2-012: add typed scoped configuration
CI / test (push) Failing after 33s
2026-08-29 11:09:33 +03:00
m 6cbef9af41 GEN2-012: add scoped configuration bootstrap boundary
CI / test (push) Failing after 34s
2026-08-29 11:08:53 +03:00
m 2fe9802e5a GEN2-011: cut PersonalMemory to compatibility fallback
CI / test (push) Failing after 37s
2026-08-29 02:41:23 +03:00
m 0882df3ad2 GEN2-010: add bounded Context Compiler V2 trace
CI / test (push) Successful in 53s
2026-08-29 02:39:58 +03:00
m 0acbe53fad GEN2-009: add rebuildable retrieval projections
CI / test (push) Successful in 50s
2026-08-29 02:38:49 +03:00
m e634bb946a GEN2-008: promote experience and episode projections
CI / test (push) Successful in 55s
2026-08-29 02:37:28 +03:00
m c7ad996cae GEN2-007: add task-relative freshness assessment
CI / test (push) Successful in 52s
2026-08-29 02:35:54 +03:00
m a065382512 GEN2-006: normalize epistemic propositions and assessments
CI / test (push) Successful in 51s
2026-08-29 02:33:09 +03:00
m 8a8e571905 GEN2-005: govern identity resolution and version bindings
CI / test (push) Failing after 38s
2026-08-29 02:20:02 +03:00
m 301dbdcfb2 GEN2-004: add ContextScope and FocusStack V2
CI / test (push) Successful in 50s
2026-08-29 02:17:36 +03:00
m 8037e66998 GEN2-003: add typed World referent foundation
CI / test (push) Successful in 50s
2026-08-29 02:11:36 +03:00
m 29815c49b8 GEN2-002: add shared semantic primitives
CI / test (push) Successful in 52s
2026-08-29 02:08:20 +03:00
75 changed files with 2502 additions and 29 deletions
+33
View File
@@ -2,6 +2,7 @@ package postgres
import (
"context"
"encoding/json"
"strings"
"git.cin.su/m/Assistant/contracts/identity"
@@ -18,6 +19,38 @@ func OpenSituation(ctx context.Context, config ContinuityConfig) (*SituationRepo
}
return &SituationRepository{pool: pool}, nil
}
func (r *SituationRepository) SaveContextScope(ctx context.Context, scope situation.ContextScope) error {
if err := scope.Validate(); err != nil {
return err
}
bindings, err := json.Marshal(scope.Bindings)
if err != nil {
return err
}
_, err = r.pool.Exec(ctx, `INSERT INTO situation.context_scopes(context_scope_id,principal_id,revision,bindings,recorded_at_unix_millis) VALUES($1,$2,$3,$4,$5) ON CONFLICT(context_scope_id) DO UPDATE SET revision=EXCLUDED.revision, bindings=EXCLUDED.bindings, recorded_at_unix_millis=EXCLUDED.recorded_at_unix_millis`, scope.ID, scope.PrincipalID, scope.Revision, bindings, scope.RecordedAt)
return err
}
func (r *SituationRepository) SaveFocusFrame(ctx context.Context, frame situation.FocusFrame) error {
if err := frame.Validate(); err != nil {
return err
}
ref, err := json.Marshal(frame.ContextScopeRef)
if err != nil {
return err
}
_, err = r.pool.Exec(ctx, `INSERT INTO situation.focus_frames(focus_frame_id,principal_id,actor_id,revision,authority_scope_ref,context_scope_ref,goal_ref,task_ref,source_utterance_ref,provenance,confidence_millis,state,parent_frame_ref,activated_at_unix_millis,suspended_at_unix_millis,expired_at_unix_millis,recorded_at_unix_millis) VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17) ON CONFLICT(focus_frame_id) DO UPDATE SET revision=EXCLUDED.revision, context_scope_ref=EXCLUDED.context_scope_ref, state=EXCLUDED.state, suspended_at_unix_millis=EXCLUDED.suspended_at_unix_millis, expired_at_unix_millis=EXCLUDED.expired_at_unix_millis, recorded_at_unix_millis=EXCLUDED.recorded_at_unix_millis`, frame.ID, frame.PrincipalID, frame.ActorID, frame.Revision, frame.AuthorityScopeRef, ref, frame.GoalRef, frame.TaskRef, frame.SourceUtteranceRef, frame.Provenance, frame.ConfidenceMillis, frame.State, frame.ParentFrameRef, frame.ActivatedAt, frame.SuspendedAt, frame.ExpiredAt, frame.RecordedAt)
return err
}
func (r *SituationRepository) AppendFocusTransition(ctx context.Context, transition situation.FocusTransition) error {
if err := transition.Validate(); err != nil {
return err
}
_, err := r.pool.Exec(ctx, `INSERT INTO situation.focus_transitions(transition_id,focus_frame_id,from_revision,to_revision,operation,cause_ref,recorded_at_unix_millis) VALUES($1,$2,$3,$4,$5,$6,$7)`, transition.TransitionID, transition.FrameID, transition.FromRevision, transition.ToRevision, transition.Operation, transition.CauseRef, transition.RecordedAt)
return err
}
func (r *SituationRepository) Close() { r.pool.Close() }
func (r *SituationRepository) Save(ctx context.Context, binding situation.FocusBinding) error {
_, err := r.pool.Exec(ctx, `INSERT INTO situation.focus_bindings (focus_binding_id, actor_id, session_id, workspace_id, project_id, goal_id, scope_id, active) VALUES ($1,$2,$3,$4,$5,$6,$7,$8) ON CONFLICT (focus_binding_id) DO UPDATE SET active=EXCLUDED.active`, binding.ID, binding.ActorID, binding.SessionID, binding.Workspace, binding.ProjectID, binding.GoalID, binding.ScopeID, binding.Active)
+108
View File
@@ -0,0 +1,108 @@
package postgres
import (
"context"
"encoding/json"
"fmt"
"git.cin.su/m/Assistant/contracts/world"
worlddomain "git.cin.su/m/Assistant/modules/world/domain"
"github.com/jackc/pgx/v5/pgxpool"
)
type WorldRepository struct{ pool *pgxpool.Pool }
func OpenWorld(ctx context.Context, config ContinuityConfig) (*WorldRepository, error) {
pool, err := openPool(ctx, config)
if err != nil {
return nil, err
}
return &WorldRepository{pool: pool}, nil
}
func (r *WorldRepository) Close() { r.pool.Close() }
func (r *WorldRepository) SaveKindDefinition(ctx context.Context, value world.WorldObjectKindDefinition) error {
if err := worlddomain.ValidateKindDefinition(value); err != nil {
return err
}
var parentOwner, parentKind, parentID string
var parentRevision *uint64
if value.ParentKindRef != nil {
parentOwner, parentKind, parentID = value.ParentKindRef.OwnerNamespace, value.ParentKindRef.SemanticKind, string(value.ParentKindRef.StableID)
if value.ParentKindRef.Revision != nil {
revision := uint64(*value.ParentKindRef.Revision)
parentRevision = &revision
}
}
_, err := r.pool.Exec(ctx, `INSERT INTO world.kind_definitions(kind_definition_id,kind_key,revision,display_name,parent_owner_namespace,parent_semantic_kind,parent_stable_id,parent_revision,lifecycle,definition_digest,recorded_at_unix_millis) VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11) ON CONFLICT(kind_definition_id) DO NOTHING`, value.ID, value.KindKey, value.Revision, value.DisplayName, parentOwner, parentKind, parentID, parentRevision, value.Lifecycle, value.DefinitionDigest, value.RecordedAt)
return err
}
func (r *WorldRepository) SaveObject(ctx context.Context, value world.WorldObject) error {
if err := worlddomain.ValidateObject(value); err != nil {
return err
}
_, err := r.pool.Exec(ctx, `INSERT INTO world.objects(world_object_id,principal_id,kind_owner_namespace,kind_semantic_kind,kind_stable_id,kind_revision,lifecycle,created_at_unix_millis) VALUES($1,$2,$3,$4,$5,$6,$7,$8) ON CONFLICT(world_object_id) DO NOTHING`, value.ID, value.PrincipalID, value.KindDefinitionRef.OwnerNamespace, value.KindDefinitionRef.SemanticKind, value.KindDefinitionRef.StableID, value.KindRevision, value.Lifecycle, value.CreatedAt)
return err
}
func (r *WorldRepository) SaveAlias(ctx context.Context, value world.WorldAlias) error {
if err := worlddomain.ValidateAlias(value); err != nil {
return err
}
_, err := r.pool.Exec(ctx, `INSERT INTO world.aliases(world_alias_id,principal_id,world_object_id,alias,recorded_at_unix_millis) VALUES($1,$2,$3,$4,$5) ON CONFLICT(world_alias_id) DO NOTHING`, value.ID, value.PrincipalID, value.ObjectID, value.Alias, value.RecordedAt)
return err
}
func (r *WorldRepository) SaveFacetDefinition(ctx context.Context, value world.FacetDefinition) error {
if err := worlddomain.ValidateFacetDefinition(value); err != nil {
return err
}
payload, err := json.Marshal(value.ValueType)
if err != nil {
return fmt.Errorf("encode facet value type: %w", err)
}
_, err = r.pool.Exec(ctx, `INSERT INTO world.facet_definitions(facet_definition_id,kind_key,revision,facet_key,value_type,definition_digest,recorded_at_unix_millis) VALUES($1,$2,$3,$4,$5,$6,$7) ON CONFLICT(facet_definition_id) DO NOTHING`, value.ID, value.KindKey, value.Revision, value.FacetKey, payload, value.DefinitionDigest, value.RecordedAt)
return err
}
func (r *WorldRepository) SaveRelationDefinition(ctx context.Context, value world.RelationDefinition) error {
if err := worlddomain.ValidateRelationDefinition(value); err != nil {
return err
}
_, err := r.pool.Exec(ctx, `INSERT INTO world.relation_definitions(relation_definition_id,kind_key,revision,relation_key,target_kind_key,definition_digest,recorded_at_unix_millis) VALUES($1,$2,$3,$4,$5,$6,$7) ON CONFLICT(relation_definition_id) DO NOTHING`, value.ID, value.KindKey, value.Revision, value.RelationKey, value.TargetKindKey, value.DefinitionDigest, value.RecordedAt)
return err
}
func (r *WorldRepository) SaveResolution(ctx context.Context, value world.IdentityResolutionDecisionRecord) error {
if err := worlddomain.ValidateResolution(value); err != nil {
return err
}
candidates, err := json.Marshal(value.Candidates)
if err != nil {
return fmt.Errorf("encode resolution candidates: %w", err)
}
evidence, err := json.Marshal(value.Evidence)
if err != nil {
return fmt.Errorf("encode resolution evidence: %w", err)
}
_, err = r.pool.Exec(ctx, `INSERT INTO world.identity_resolution_decisions(resolution_decision_id,principal_id,candidates,decision,evidence,confidence_millis,decided_at_unix_millis,revision) VALUES($1,$2,$3,$4,$5,$6,$7,$8) ON CONFLICT(resolution_decision_id) DO NOTHING`, value.ID, value.PrincipalID, candidates, value.Decision, evidence, value.ConfidenceMillis, value.DecidedAt, value.Revision)
return err
}
func (r *WorldRepository) SaveLineage(ctx context.Context, value world.WorldLineage) error {
if err := worlddomain.ValidateLineage(value); err != nil {
return err
}
sources, err := json.Marshal(value.SourceRefs)
if err != nil {
return fmt.Errorf("encode lineage sources: %w", err)
}
successors, err := json.Marshal(value.SuccessorRefs)
if err != nil {
return fmt.Errorf("encode lineage successors: %w", err)
}
_, err = r.pool.Exec(ctx, `INSERT INTO world.lineage(lineage_id,operation,source_refs,successor_refs,recorded_at_unix_millis) VALUES($1,$2,$3,$4,$5) ON CONFLICT(lineage_id) DO NOTHING`, value.ID, value.Operation, sources, successors, value.RecordedAt)
return err
}
+4 -4
View File
@@ -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,
+10
View File
@@ -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"))
}))
}
+41
View File
@@ -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"}
}
+61
View File
@@ -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
}
+36
View File
@@ -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
}
+41 -5
View File
@@ -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)
}
}
+32
View File
@@ -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
}
+7
View File
@@ -0,0 +1,7 @@
package configuration
import "git.cin.su/m/Assistant/platform/ids"
// SemanticReference is a typed cross-owner reference; settings remain
// Configuration-owned records.
type SemanticReference = ids.SemanticRef
+98
View File
@@ -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
}
+90
View File
@@ -0,0 +1,90 @@
package epistemics
import (
"fmt"
"git.cin.su/m/Assistant/contracts/world"
)
type VolatilityMode string
const (
VolatilityImmutable VolatilityMode = "IMMUTABLE"
VolatilityVersionBound VolatilityMode = "VERSION_BOUND"
VolatilityVerySlow VolatilityMode = "VERY_SLOW"
VolatilitySlow VolatilityMode = "SLOW"
VolatilityMedium VolatilityMode = "MEDIUM"
VolatilityFast VolatilityMode = "FAST"
VolatilityEphemeral VolatilityMode = "EPHEMERAL"
VolatilityCustom VolatilityMode = "CUSTOM"
)
type TemporalApplicability struct {
ObservedAtUnixMillis int64
ValidFromUnixMillis *int64
ValidUntilUnixMillis *int64
LastVerifiedAtUnixMillis *int64
Volatility VolatilitySpec
VersionBindings []world.VersionBinding
}
type VolatilitySpec struct {
Mode VolatilityMode
ExpectedChangeIntervalMillis *int64
RevalidateAfterMillis *int64
HardStaleAfterMillis *int64
InvalidateOnVersionChange bool
RevalidationPolicyRef string
}
type FreshnessAssessmentState string
const (
FreshnessAssessmentCurrent FreshnessAssessmentState = "CURRENT"
FreshnessAssessmentAcceptable FreshnessAssessmentState = "ACCEPTABLE"
FreshnessAssessmentAging FreshnessAssessmentState = "AGING"
FreshnessAssessmentStale FreshnessAssessmentState = "STALE"
FreshnessAssessmentVersionMismatch FreshnessAssessmentState = "VERSION_MISMATCH"
FreshnessAssessmentHistoricalOnly FreshnessAssessmentState = "HISTORICAL_ONLY"
FreshnessAssessmentUnknown FreshnessAssessmentState = "UNKNOWN"
)
type FreshnessAssessment struct {
SourceKnowledgeRef string
TaskRef string
State FreshnessAssessmentState
Reason string
AgeMillis int64
VersionMatchState string
RevalidationAttemptRef string
AssessedAtUnixMillis int64
}
type RevalidationRequest struct {
ID string
SourceKnowledgeRef string
TaskRef string
RequiredVersionRefs []world.SemanticReference
RequestedAtUnixMillis int64
}
type RevalidationResponse struct {
RequestID string
Assessment FreshnessAssessment
NewEvidenceRefs []EvidenceRef
CompletedAtUnixMillis int64
}
func (v VolatilitySpec) Validate() error {
if v.Mode == "" {
return fmt.Errorf("volatility mode is required")
}
return nil
}
func (t TemporalApplicability) Validate() error {
if t.ObservedAtUnixMillis < 1 {
return fmt.Errorf("observed time is required")
}
return t.Volatility.Validate()
}
func (a FreshnessAssessment) Validate() error {
if a.SourceKnowledgeRef == "" || a.TaskRef == "" || a.State == "" || a.AgeMillis < 0 || a.AssessedAtUnixMillis < 1 {
return fmt.Errorf("freshness assessment is incomplete")
}
return nil
}
+30
View File
@@ -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
}
+7
View File
@@ -0,0 +1,7 @@
package epistemics
import "git.cin.su/m/Assistant/platform/ids"
// SemanticReference identifies evidence-related records without transferring
// canonical ownership to Epistemics.
type SemanticReference = ids.SemanticRef
+20 -10
View File
@@ -1,5 +1,7 @@
package epistemics
import "git.cin.su/m/Assistant/platform/ids"
type BeliefState string
const (
@@ -9,19 +11,27 @@ const (
)
type Observation struct {
ID ObservationID
SourceSnapshot SourceSnapshotID
Excerpt SourceExcerptID
Text string
ObservedAt int64
ID ObservationID
SourceSnapshot SourceSnapshotID
Excerpt SourceExcerptID
Text string
ObservedAt int64
PrincipalID string
ContextScopeRef string
ObservationKind string
Payload string
ExtractorRef string
}
type Claim struct {
ID ClaimID
Statement string
ObservationID ObservationID
CitationID CitationID
Verification VerificationState
ID ClaimID
Statement string
ObservationID ObservationID
CitationID CitationID
Verification VerificationState
PropositionID ids.ID
RevisedFrom *ClaimID
RecordedAtUnixMillis int64
}
type Belief struct {
+48
View File
@@ -24,6 +24,8 @@ type HelpMethodKind string
type OutcomeClass string
type ReflectionTriggerKind string
type ReflectionCandidateState string
type PropositionKind string
type BeliefAssessmentState string
const (
VerificationUnverified VerificationState = "UNVERIFIED"
@@ -73,6 +75,12 @@ const (
ReflectionCandidateEvaluating ReflectionCandidateState = "EVALUATING"
ReflectionCandidateSuperseded ReflectionCandidateState = "SUPERSEDED"
ReflectionCandidateResolved ReflectionCandidateState = "RESOLVED"
PropositionWorldFacet PropositionKind = "WORLD_FACET"
PropositionWorldRelation PropositionKind = "WORLD_RELATION"
PropositionOwnerDefined PropositionKind = "OWNER_DEFINED"
PropositionTextual PropositionKind = "TEXTUAL"
BeliefAssessmentCurrent BeliefAssessmentState = "CURRENT"
BeliefAssessmentSuperseded BeliefAssessmentState = "SUPERSEDED"
)
// SystemExpectation records what Domovoy expected a meaningful help path to
@@ -114,6 +122,15 @@ type ExperienceRecord struct {
VerificationEvidence []EvidenceRef
ConfidenceMillis int64
RecordedAtUnixMillis int64
ProblemStatement string
AttemptRef string
WhyAttempted string
ApplicabilityConditions []string
ContextScopeRef string
EpisodeRef string
GoalRef string
TaskRef string
WhySucceededOrFailed string
}
// ReflectionCandidate records that broader reflection may be warranted.
@@ -134,3 +151,34 @@ type ReflectionCandidate struct {
ClaimedBy string
ClaimExpiresAtUnixMillis int64
}
type Proposition struct {
ID ids.ID
Kind PropositionKind
SubjectRef string
PredicateRef string
ObjectValue string
ObjectRef string
Qualifiers []string
TextFallback string
}
type BeliefAssessment struct {
ID ids.ID
ClaimID ClaimID
Revision ids.Revision
State BeliefAssessmentState
ConfidenceMillis int64
EvidenceRefs []EvidenceRef
AssessedAtUnixMillis int64
}
type EpisodeID ids.ID
type Episode struct {
ID EpisodeID
PrincipalID string
ExperienceRefs []ExperienceRecordID
Summary string
Outcome OutcomeClass
RecordedAtUnixMillis int64
}
+25
View File
@@ -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
}
+7
View File
@@ -0,0 +1,7 @@
package self
import "git.cin.su/m/Assistant/platform/ids"
// SemanticReference lets SELF cite evidence and capabilities without owning
// their canonical state.
type SemanticReference = ids.SemanticRef
+92
View File
@@ -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
}
+141
View File
@@ -0,0 +1,141 @@
package situation
import (
"fmt"
"git.cin.su/m/Assistant/contracts/authority"
"git.cin.su/m/Assistant/contracts/identity"
"git.cin.su/m/Assistant/contracts/work"
"git.cin.su/m/Assistant/platform/clock"
"git.cin.su/m/Assistant/platform/ids"
)
type ContextScopeID ids.StableID
type FocusFrameID ids.StableID
type FocusTransitionID ids.StableID
type FocusRevision ids.Revision
type RoleKey string
type MatchPolicy string
type FocusFrameState string
type FocusProvenance string
type FocusTransitionOperation string
const (
MatchRequired MatchPolicy = "REQUIRED"
MatchPreferred MatchPolicy = "PREFERRED"
MatchRelated MatchPolicy = "RELATED"
MatchExcluded MatchPolicy = "EXCLUDED"
RolePerson RoleKey = "PERSON"
RoleOrganization RoleKey = "ORGANIZATION"
RoleFamily RoleKey = "FAMILY"
RoleEnvironment RoleKey = "ENVIRONMENT"
RoleLocation RoleKey = "LOCATION"
RoleSystem RoleKey = "SYSTEM"
RoleDatabase RoleKey = "DATABASE"
RoleRepository RoleKey = "REPOSITORY"
RoleBranch RoleKey = "BRANCH"
RoleVersion RoleKey = "VERSION"
RoleActivity RoleKey = "ACTIVITY"
RoleProject RoleKey = "PROJECT"
RoleActiveEntity RoleKey = "ACTIVE_ENTITY"
FocusCandidate FocusFrameState = "CANDIDATE"
FocusActive FocusFrameState = "ACTIVE"
FocusSuspended FocusFrameState = "SUSPENDED"
FocusExpired FocusFrameState = "EXPIRED"
FocusSuperseded FocusFrameState = "SUPERSEDED"
FocusExplicitHuman FocusProvenance = "EXPLICIT_HUMAN"
FocusUserConfirmed FocusProvenance = "USER_CONFIRMED"
FocusInherited FocusProvenance = "INHERITED"
FocusEntityReference FocusProvenance = "ENTITY_REFERENCE"
FocusTaskReference FocusProvenance = "TASK_REFERENCE"
FocusRepositoryReference FocusProvenance = "REPOSITORY_REFERENCE"
FocusEnvironmentObservation FocusProvenance = "ENVIRONMENT_OBSERVATION"
FocusInferred FocusProvenance = "INFERRED"
TransitionActivate FocusTransitionOperation = "ACTIVATE"
TransitionSuspend FocusTransitionOperation = "SUSPEND"
TransitionResume FocusTransitionOperation = "RESUME"
TransitionSupersede FocusTransitionOperation = "SUPERSEDE"
TransitionExpire FocusTransitionOperation = "EXPIRE"
)
type ContextBinding struct {
RoleKey RoleKey
TargetRef SemanticReference
MatchPolicy MatchPolicy
Provenance string
ConfidenceMillis int64
SourceRef *SemanticReference
}
type ContextScope struct {
ID ContextScopeID
PrincipalID identity.PrincipalID
Revision FocusRevision
Bindings []ContextBinding
RecordedAt clock.Instant
}
type FocusFrame struct {
ID FocusFrameID
PrincipalID identity.PrincipalID
ActorID identity.ActorID
Revision FocusRevision
AuthorityScopeRef authority.ScopeID
ContextScopeRef SemanticReference
GoalRef *work.GoalID
TaskRef *work.TaskID
SourceUtteranceRef string
Provenance FocusProvenance
ConfidenceMillis int64
State FocusFrameState
ParentFrameRef *FocusFrameID
ActivatedAt clock.Instant
SuspendedAt *clock.Instant
ExpiredAt *clock.Instant
RecordedAt clock.Instant
}
type FocusTransition struct {
TransitionID FocusTransitionID
FrameID FocusFrameID
FromRevision FocusRevision
ToRevision FocusRevision
Operation FocusTransitionOperation
CauseRef string
RecordedAt clock.Instant
}
func (s ContextScope) Validate() error {
if s.ID == "" || s.PrincipalID == "" || !ids.Revision(s.Revision).Valid() || !s.RecordedAt.Valid() {
return fmt.Errorf("invalid context scope")
}
for _, b := range s.Bindings {
if b.RoleKey == "" || !b.TargetRef.Valid() || !validMatchPolicy(b.MatchPolicy) {
return fmt.Errorf("invalid context binding")
}
}
return nil
}
func (f FocusFrame) Validate() error {
if f.ID == "" || f.PrincipalID == "" || f.ActorID == "" || !ids.Revision(f.Revision).Valid() || !f.ContextScopeRef.Valid() || f.State == "" || f.Provenance == "" || !f.RecordedAt.Valid() {
return fmt.Errorf("invalid focus frame")
}
return nil
}
func (t FocusTransition) Validate() error {
if t.TransitionID == "" || t.FrameID == "" || !ids.Revision(t.FromRevision).Valid() || !ids.Revision(t.ToRevision).Valid() || t.Operation == "" || !t.RecordedAt.Valid() {
return fmt.Errorf("invalid focus transition")
}
return nil
}
func validMatchPolicy(p MatchPolicy) bool {
return p == MatchRequired || p == MatchPreferred || p == MatchRelated || p == MatchExcluded
}
+22
View File
@@ -0,0 +1,22 @@
package situation_test
import (
"testing"
"git.cin.su/m/Assistant/contracts/identity"
contract "git.cin.su/m/Assistant/contracts/situation"
"git.cin.su/m/Assistant/platform/clock"
"git.cin.su/m/Assistant/platform/ids"
)
func TestFocusV2ContractsValidateTypedScopeAndFrame(t *testing.T) {
rev := ids.Revision(1)
scope := contract.ContextScope{ID: "scope", PrincipalID: identity.PrincipalID("company-a"), Revision: contract.FocusRevision(rev), RecordedAt: clock.Instant(1), Bindings: []contract.ContextBinding{{RoleKey: contract.RoleOrganization, TargetRef: contract.SemanticReference{OwnerNamespace: "world", SemanticKind: "organization", StableID: "a"}, MatchPolicy: contract.MatchRequired}}}
if err := scope.Validate(); err != nil {
t.Fatal(err)
}
frame := contract.FocusFrame{ID: "frame", PrincipalID: scope.PrincipalID, ActorID: "actor", Revision: 1, ContextScopeRef: contract.SemanticReference{OwnerNamespace: "situation", SemanticKind: "context_scope", StableID: ids.StableID(scope.ID), Revision: &rev}, State: contract.FocusActive, Provenance: contract.FocusExplicitHuman, RecordedAt: 1}
if err := frame.Validate(); err != nil {
t.Fatal(err)
}
}
+7
View File
@@ -0,0 +1,7 @@
package situation
import "git.cin.su/m/Assistant/platform/ids"
// SemanticReference keeps Situation references transport-neutral while
// ContextScope semantics remain owned by Situation.
type SemanticReference = ids.SemanticRef
+24
View File
@@ -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
}
+28
View File
@@ -0,0 +1,28 @@
package work
import "git.cin.su/m/Assistant/contracts/world"
type FreshnessRequirementMode string
type FreshnessFallbackPolicy string
const (
FreshnessAny FreshnessRequirementMode = "ANY"
FreshnessPreferCurrent FreshnessRequirementMode = "PREFER_CURRENT"
FreshnessRequireCurrent FreshnessRequirementMode = "REQUIRE_CURRENT"
FreshnessRequireWithinAge FreshnessRequirementMode = "REQUIRE_WITHIN_AGE"
FreshnessRequireVersionMatch FreshnessRequirementMode = "REQUIRE_VERSION_MATCH"
FreshnessLiveRequired FreshnessRequirementMode = "LIVE_REQUIRED"
FallbackAllowStaleDisclosure FreshnessFallbackPolicy = "ALLOW_STALE_WITH_DISCLOSURE"
FallbackHypothesisOnly FreshnessFallbackPolicy = "USE_AS_HYPOTHESIS_ONLY"
FallbackWaitForSource FreshnessFallbackPolicy = "WAIT_FOR_SOURCE"
FallbackAskOwner FreshnessFallbackPolicy = "ASK_OWNER"
FallbackStopUnknown FreshnessFallbackPolicy = "STOP_WITH_UNKNOWN"
)
type TaskFreshnessRequirement struct {
Mode FreshnessRequirementMode
MaximumAgeMillis *int64
RequiredVersionRefs []world.SemanticReference
RevalidationRequired bool
FallbackPolicy FreshnessFallbackPolicy
}
+35
View File
@@ -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
}
+26
View File
@@ -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 != ""
}
+312
View File
@@ -0,0 +1,312 @@
package world
import (
"fmt"
"git.cin.su/m/Assistant/contracts/identity"
"git.cin.su/m/Assistant/platform/clock"
"git.cin.su/m/Assistant/platform/ids"
)
// SemanticReference is the transport envelope used by World contracts. It is
// a reference only; it does not expose another owner's storage.
type SemanticReference = ids.SemanticRef
// VersionBinding is a typed applicability constraint. Absence of VersionRef
// means unknown, never an implicit "latest".
type VersionMatchMode string
const (
VersionExact VersionMatchMode = "EXACT"
VersionCompatibleFamily VersionMatchMode = "COMPATIBLE_FAMILY"
VersionAtOrBefore VersionMatchMode = "AT_OR_BEFORE"
VersionUnknown VersionMatchMode = "UNKNOWN"
)
type VersionBinding struct {
SubjectRef SemanticReference
VersionRef SemanticReference
MatchMode VersionMatchMode
}
type EnvironmentReference struct {
EnvironmentRef SemanticReference
VersionRef *SemanticReference
}
func (b VersionBinding) Validate() error {
if !b.SubjectRef.Valid() || !b.VersionRef.Valid() {
return fmt.Errorf("version binding references are invalid")
}
if b.MatchMode != VersionExact && b.MatchMode != VersionCompatibleFamily && b.MatchMode != VersionAtOrBefore && b.MatchMode != VersionUnknown {
return fmt.Errorf("version binding match mode is invalid")
}
return nil
}
func (r EnvironmentReference) Validate() error {
if !r.EnvironmentRef.Valid() {
return fmt.Errorf("environment reference is invalid")
}
if r.VersionRef != nil && !r.VersionRef.Valid() {
return fmt.Errorf("environment version reference is invalid")
}
return nil
}
type PrincipalRealm string
const (
RealmPersonal PrincipalRealm = "PERSONAL"
RealmShared PrincipalRealm = "SHARED"
RealmPublic PrincipalRealm = "PUBLIC"
RealmSystem PrincipalRealm = "SYSTEM"
)
type SensitivityClass string
const (
SensitivityPublic SensitivityClass = "PUBLIC"
SensitivityPrivate SensitivityClass = "PRIVATE"
SensitivityRestricted SensitivityClass = "RESTRICTED"
SensitivitySecretReference SensitivityClass = "SECRET_REFERENCE"
)
type ValueTypeKind string
const (
ValueString ValueTypeKind = "STRING"
ValueInteger ValueTypeKind = "INTEGER"
ValueDecimal ValueTypeKind = "DECIMAL"
ValueBoolean ValueTypeKind = "BOOLEAN"
ValueTime ValueTypeKind = "TIME"
ValueDuration ValueTypeKind = "DURATION"
ValueEnum ValueTypeKind = "ENUM"
ValueReference ValueTypeKind = "REFERENCE"
ValueBinaryRef ValueTypeKind = "BINARY_REF"
ValueList ValueTypeKind = "LIST"
ValueStruct ValueTypeKind = "STRUCT"
)
type ValueField struct {
Name string
Type ValueTypeSpec
}
type ValueTypeSpec struct {
Kind ValueTypeKind
Element *ValueTypeSpec
Fields []ValueField
EnumValues []string
ReferenceKind string
}
type WorldObjectID ids.StableID
type KindDefinitionID ids.StableID
type WorldAliasID ids.StableID
type FacetDefinitionID ids.StableID
type RelationDefinitionID ids.StableID
type ResolutionDecisionID ids.StableID
type LineageID ids.StableID
type LifecycleState string
const (
LifecycleActive LifecycleState = "ACTIVE"
LifecycleMerged LifecycleState = "MERGED"
LifecycleSplit LifecycleState = "SPLIT"
LifecycleRetired LifecycleState = "RETIRED"
LifecycleUnknownIdentity LifecycleState = "UNKNOWN_IDENTITY"
)
type WorldObject struct {
ID WorldObjectID
PrincipalID identity.PrincipalID
KindDefinitionRef SemanticReference
KindRevision ids.Revision
Lifecycle LifecycleState
CreatedAt clock.Instant
}
type WorldObjectKindDefinition struct {
ID KindDefinitionID
KindKey string
Revision ids.Revision
DisplayName string
ParentKindRef *SemanticReference
Lifecycle LifecycleState
DefinitionDigest string
RecordedAt clock.Instant
}
type WorldAlias struct {
ID WorldAliasID
PrincipalID identity.PrincipalID
ObjectID WorldObjectID
Alias string
RecordedAt clock.Instant
}
type FacetDefinition struct {
ID FacetDefinitionID
KindKey string
Revision ids.Revision
FacetKey string
ValueType ValueTypeSpec
DefinitionDigest string
RecordedAt clock.Instant
}
type RelationDefinition struct {
ID RelationDefinitionID
KindKey string
Revision ids.Revision
RelationKey string
TargetKindKey string
DefinitionDigest string
RecordedAt clock.Instant
}
type ResolutionDecision string
const (
ResolutionSame ResolutionDecision = "SAME"
ResolutionDistinct ResolutionDecision = "DISTINCT"
ResolutionMerge ResolutionDecision = "MERGE"
ResolutionSplit ResolutionDecision = "SPLIT"
ResolutionUnresolved ResolutionDecision = "UNRESOLVED"
)
type IdentityResolutionCandidate struct {
ObjectRef SemanticReference
Evidence []SemanticReference
Confidence int64
}
type IdentityResolutionDecisionRecord struct {
ID ResolutionDecisionID
PrincipalID identity.PrincipalID
Candidates []IdentityResolutionCandidate
Decision ResolutionDecision
Evidence []SemanticReference
ConfidenceMillis int64
DecidedAt clock.Instant
Revision ids.Revision
}
type WorldLineage struct {
ID LineageID
Operation ResolutionDecision
SourceRefs []SemanticReference
SuccessorRefs []SemanticReference
RecordedAt clock.Instant
}
func (w WorldObject) Validate() error {
if w.ID == "" || !w.KindDefinitionRef.Valid() || !w.KindRevision.Valid() || !validLifecycle(w.Lifecycle) || !w.CreatedAt.Valid() {
return fmt.Errorf("world object is incomplete")
}
return nil
}
func (k WorldObjectKindDefinition) Validate() error {
if k.ID == "" || k.KindKey == "" || !k.Revision.Valid() || k.DisplayName == "" || !validLifecycle(k.Lifecycle) || k.DefinitionDigest == "" || !k.RecordedAt.Valid() {
return fmt.Errorf("world kind definition is incomplete")
}
if k.ParentKindRef != nil && !k.ParentKindRef.Valid() {
return fmt.Errorf("world kind parent reference is invalid")
}
return nil
}
func (a WorldAlias) Validate() error {
if a.ID == "" || a.ObjectID == "" || a.Alias == "" || !a.RecordedAt.Valid() {
return fmt.Errorf("world alias is incomplete")
}
return nil
}
func (f FacetDefinition) Validate() error {
if f.ID == "" || f.KindKey == "" || !f.Revision.Valid() || f.FacetKey == "" || f.DefinitionDigest == "" || !f.RecordedAt.Valid() {
return fmt.Errorf("facet definition is incomplete")
}
return f.ValueType.Validate()
}
func (r RelationDefinition) Validate() error {
if r.ID == "" || r.KindKey == "" || !r.Revision.Valid() || r.RelationKey == "" || r.TargetKindKey == "" || r.DefinitionDigest == "" || !r.RecordedAt.Valid() {
return fmt.Errorf("relation definition is incomplete")
}
return nil
}
func (d IdentityResolutionDecisionRecord) Validate() error {
if d.ID == "" || !validDecision(d.Decision) || len(d.Candidates) == 0 || d.ConfidenceMillis < 0 || !d.DecidedAt.Valid() || !d.Revision.Valid() {
return fmt.Errorf("identity resolution decision is incomplete")
}
for _, candidate := range d.Candidates {
if !candidate.ObjectRef.Valid() || candidate.Confidence < 0 || candidate.Confidence > 1000 {
return fmt.Errorf("identity resolution candidate is invalid")
}
for _, evidence := range candidate.Evidence {
if !evidence.Valid() {
return fmt.Errorf("identity resolution evidence reference is invalid")
}
}
}
return nil
}
func (l WorldLineage) Validate() error {
if l.ID == "" || (l.Operation != ResolutionMerge && l.Operation != ResolutionSplit) || len(l.SourceRefs) == 0 || len(l.SuccessorRefs) == 0 || !l.RecordedAt.Valid() {
return fmt.Errorf("world lineage is incomplete")
}
return nil
}
func validLifecycle(value LifecycleState) bool {
return value == LifecycleActive || value == LifecycleMerged || value == LifecycleSplit || value == LifecycleRetired || value == LifecycleUnknownIdentity
}
func validDecision(value ResolutionDecision) bool {
return value == ResolutionSame || value == ResolutionDistinct || value == ResolutionMerge || value == ResolutionSplit || value == ResolutionUnresolved
}
func (s ValueTypeSpec) Validate() error {
if s.Kind == "" {
return fmt.Errorf("value type kind is required")
}
switch s.Kind {
case ValueList:
if s.Element == nil {
return fmt.Errorf("list element type is required")
}
return s.Element.Validate()
case ValueStruct:
if len(s.Fields) == 0 {
return fmt.Errorf("struct fields are required")
}
seen := map[string]struct{}{}
for _, field := range s.Fields {
if field.Name == "" {
return fmt.Errorf("struct field name is required")
}
if _, ok := seen[field.Name]; ok {
return fmt.Errorf("duplicate struct field %q", field.Name)
}
seen[field.Name] = struct{}{}
if err := field.Type.Validate(); err != nil {
return fmt.Errorf("field %s: %w", field.Name, err)
}
}
case ValueEnum:
if len(s.EnumValues) == 0 {
return fmt.Errorf("enum values are required")
}
case ValueReference:
if s.ReferenceKind == "" {
return fmt.Errorf("reference kind is required")
}
}
return nil
}
+17
View File
@@ -0,0 +1,17 @@
package world
import "testing"
func TestValueTypeSpecValidatesTypedRecursiveShape(t *testing.T) {
spec := ValueTypeSpec{Kind: ValueStruct, Fields: []ValueField{{Name: "name", Type: ValueTypeSpec{Kind: ValueString}}, {Name: "refs", Type: ValueTypeSpec{Kind: ValueList, Element: &ValueTypeSpec{Kind: ValueReference, ReferenceKind: "world.object"}}}}}
if err := spec.Validate(); err != nil {
t.Fatalf("ValueTypeSpec.Validate() = %v", err)
}
}
func TestValueTypeSpecRejectsDuplicateFields(t *testing.T) {
spec := ValueTypeSpec{Kind: ValueStruct, Fields: []ValueField{{Name: "same", Type: ValueTypeSpec{Kind: ValueString}}, {Name: "same", Type: ValueTypeSpec{Kind: ValueString}}}}
if err := spec.Validate(); err == nil {
t.Fatal("duplicate fields were accepted")
}
}
+22
View File
@@ -0,0 +1,22 @@
package world
import (
"testing"
"git.cin.su/m/Assistant/platform/clock"
"git.cin.su/m/Assistant/platform/ids"
)
func TestWorldObjectValidationKeepsReferentSeparateFromClaims(t *testing.T) {
object := WorldObject{ID: "object-1", KindDefinitionRef: ids.SemanticRef{OwnerNamespace: "world", SemanticKind: "kind", StableID: "kind-1"}, KindRevision: 1, Lifecycle: LifecycleActive, CreatedAt: clock.Instant(1)}
if err := object.Validate(); err != nil {
t.Fatalf("WorldObject.Validate() = %v", err)
}
}
func TestIdentityResolutionRequiresEvidenceBackedCandidates(t *testing.T) {
decision := IdentityResolutionDecisionRecord{ID: "decision-1", Decision: ResolutionSame, Candidates: []IdentityResolutionCandidate{{ObjectRef: ids.SemanticRef{OwnerNamespace: "world", SemanticKind: "object", StableID: "object-1"}, Confidence: 900}}, DecidedAt: clock.Instant(1), Revision: 1}
if err := decision.Validate(); err != nil {
t.Fatalf("IdentityResolutionDecisionRecord.Validate() = %v", err)
}
}
@@ -0,0 +1,82 @@
BEGIN;
CREATE SCHEMA IF NOT EXISTS world;
SET ROLE world_role;
CREATE TABLE IF NOT EXISTS world.kind_definitions (
kind_definition_id TEXT PRIMARY KEY,
kind_key TEXT NOT NULL,
revision BIGINT NOT NULL CHECK (revision > 0),
display_name TEXT NOT NULL,
parent_owner_namespace TEXT NOT NULL DEFAULT '',
parent_semantic_kind TEXT NOT NULL DEFAULT '',
parent_stable_id TEXT NOT NULL DEFAULT '',
parent_revision BIGINT,
lifecycle TEXT NOT NULL,
definition_digest TEXT NOT NULL,
recorded_at_unix_millis BIGINT NOT NULL CHECK (recorded_at_unix_millis > 0),
UNIQUE (kind_key, revision)
);
CREATE TABLE IF NOT EXISTS world.objects (
world_object_id TEXT PRIMARY KEY,
principal_id TEXT,
kind_owner_namespace TEXT NOT NULL,
kind_semantic_kind TEXT NOT NULL,
kind_stable_id TEXT NOT NULL,
kind_revision BIGINT,
lifecycle TEXT NOT NULL,
created_at_unix_millis BIGINT NOT NULL CHECK (created_at_unix_millis > 0)
);
CREATE TABLE IF NOT EXISTS world.aliases (
world_alias_id TEXT PRIMARY KEY,
principal_id TEXT,
world_object_id TEXT NOT NULL,
alias TEXT NOT NULL,
recorded_at_unix_millis BIGINT NOT NULL CHECK (recorded_at_unix_millis > 0)
);
CREATE TABLE IF NOT EXISTS world.facet_definitions (
facet_definition_id TEXT PRIMARY KEY,
kind_key TEXT NOT NULL,
revision BIGINT NOT NULL CHECK (revision > 0),
facet_key TEXT NOT NULL,
value_type JSONB NOT NULL,
definition_digest TEXT NOT NULL,
recorded_at_unix_millis BIGINT NOT NULL CHECK (recorded_at_unix_millis > 0),
UNIQUE (kind_key, facet_key, revision)
);
CREATE TABLE IF NOT EXISTS world.relation_definitions (
relation_definition_id TEXT PRIMARY KEY,
kind_key TEXT NOT NULL,
revision BIGINT NOT NULL CHECK (revision > 0),
relation_key TEXT NOT NULL,
target_kind_key TEXT NOT NULL,
definition_digest TEXT NOT NULL,
recorded_at_unix_millis BIGINT NOT NULL CHECK (recorded_at_unix_millis > 0),
UNIQUE (kind_key, relation_key, revision)
);
CREATE TABLE IF NOT EXISTS world.identity_resolution_decisions (
resolution_decision_id TEXT PRIMARY KEY,
principal_id TEXT,
candidates JSONB NOT NULL,
decision TEXT NOT NULL,
evidence JSONB NOT NULL,
confidence_millis BIGINT NOT NULL CHECK (confidence_millis >= 0),
decided_at_unix_millis BIGINT NOT NULL CHECK (decided_at_unix_millis > 0),
revision BIGINT NOT NULL CHECK (revision > 0)
);
CREATE TABLE IF NOT EXISTS world.lineage (
lineage_id TEXT PRIMARY KEY,
operation TEXT NOT NULL,
source_refs JSONB NOT NULL,
successor_refs JSONB NOT NULL,
recorded_at_unix_millis BIGINT NOT NULL CHECK (recorded_at_unix_millis > 0)
);
RESET ROLE;
COMMIT;
@@ -0,0 +1,47 @@
BEGIN;
SET ROLE situation_role;
CREATE TABLE IF NOT EXISTS situation.context_scopes (
context_scope_id TEXT PRIMARY KEY,
principal_id TEXT NOT NULL,
revision BIGINT NOT NULL CHECK (revision > 0),
bindings JSONB NOT NULL,
recorded_at_unix_millis BIGINT NOT NULL CHECK (recorded_at_unix_millis > 0)
);
CREATE TABLE IF NOT EXISTS situation.focus_frames (
focus_frame_id TEXT PRIMARY KEY,
principal_id TEXT NOT NULL,
actor_id TEXT NOT NULL,
revision BIGINT NOT NULL CHECK (revision > 0),
authority_scope_ref TEXT NOT NULL,
context_scope_ref JSONB NOT NULL,
goal_ref TEXT,
task_ref TEXT,
source_utterance_ref TEXT,
provenance TEXT NOT NULL,
confidence_millis BIGINT NOT NULL CHECK (confidence_millis >= 0),
state TEXT NOT NULL,
parent_frame_ref TEXT,
activated_at_unix_millis BIGINT NOT NULL CHECK (activated_at_unix_millis > 0),
suspended_at_unix_millis BIGINT,
expired_at_unix_millis BIGINT,
recorded_at_unix_millis BIGINT NOT NULL CHECK (recorded_at_unix_millis > 0)
);
CREATE TABLE IF NOT EXISTS situation.focus_transitions (
transition_id TEXT PRIMARY KEY,
focus_frame_id TEXT NOT NULL,
from_revision BIGINT NOT NULL CHECK (from_revision > 0),
to_revision BIGINT NOT NULL CHECK (to_revision > 0),
operation TEXT NOT NULL,
cause_ref TEXT NOT NULL,
recorded_at_unix_millis BIGINT NOT NULL CHECK (recorded_at_unix_millis > 0)
);
CREATE INDEX IF NOT EXISTS focus_transitions_frame_order ON situation.focus_transitions(focus_frame_id, recorded_at_unix_millis, transition_id);
GRANT SELECT, INSERT, UPDATE ON situation.context_scopes, situation.focus_frames, situation.focus_transitions TO situation_role;
RESET ROLE;
COMMIT;
@@ -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 -5
View File
@@ -1,5 +1 @@
{
"task_file": "dev/tasks/GEN2-001-accept-gen2-owner-registry-and-dependency-rules.json",
"task_id": "GEN2-001",
"task_revision": 1
}
{"task_file":"dev/tasks/GEN2-021-add-independent-supervisor-lifeboat-for-release-health-and-rollback.json","task_id":"GEN2-021","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)
}
}
+22
View File
@@ -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"
}
+21
View File
@@ -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")
}
}
+16
View File
@@ -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
}
+4
View File
@@ -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)}}
+29
View File
@@ -0,0 +1,29 @@
package domain
import (
"git.cin.su/m/Assistant/contracts/epistemics"
"git.cin.su/m/Assistant/platform/ids"
"strings"
)
func BuildEpisode(experiences []epistemics.ExperienceRecord, summary string, at int64) (epistemics.Episode, error) {
if len(experiences) == 0 || strings.TrimSpace(summary) == "" || at < 1 {
return epistemics.Episode{}, ErrInvalidExperience
}
refs := make([]epistemics.ExperienceRecordID, 0, len(experiences))
outcome := epistemics.OutcomeUnknown
for _, e := range experiences {
if _, err := NewExperienceRecord(e); err != nil {
return epistemics.Episode{}, err
}
refs = append(refs, e.ID)
if e.ActualOutcome != epistemics.OutcomeSuccess {
outcome = e.ActualOutcome
}
}
id, err := ids.New()
if err != nil {
return epistemics.Episode{}, err
}
return epistemics.Episode{ID: epistemics.EpisodeID(id), ExperienceRefs: refs, Summary: summary, Outcome: outcome, RecordedAtUnixMillis: at}, nil
}
+15
View File
@@ -0,0 +1,15 @@
package domain_test
import (
"git.cin.su/m/Assistant/contracts/epistemics"
"git.cin.su/m/Assistant/modules/epistemics/domain"
"testing"
)
func TestEpisodeIsRebuildableFromExperience(t *testing.T) {
e := epistemics.ExperienceRecord{ID: "e", SourceKind: epistemics.ExperienceSourceInteraction, OriginalIntentID: "i", SourceUtteranceID: "u", HelpMethod: epistemics.HelpMethodFallback, ExpectedOutcome: epistemics.OutcomeSuccess, ActualOutcome: epistemics.OutcomeFailed, RecordedAtUnixMillis: 1}
ep, err := domain.BuildEpisode([]epistemics.ExperienceRecord{e}, "failed attempt", 1)
if err != nil || len(ep.ExperienceRefs) != 1 || ep.Outcome != epistemics.OutcomeFailed {
t.Fatalf("episode=%#v err=%v", ep, err)
}
}
+30
View File
@@ -0,0 +1,30 @@
package domain
import "git.cin.su/m/Assistant/contracts/epistemics"
// AssessFreshness receives the Work-owned requirement as primitive policy
// inputs, keeping the Epistemics owner independent of Work package types.
func AssessFreshness(applicability epistemics.TemporalApplicability, mode string, maximumAgeMillis *int64, nowMillis int64) epistemics.FreshnessAssessment {
age := nowMillis - applicability.ObservedAtUnixMillis
if age < 0 {
age = 0
}
state := epistemics.FreshnessAssessmentCurrent
reason := "observation is within applicability window"
if applicability.ValidUntilUnixMillis != nil && nowMillis > *applicability.ValidUntilUnixMillis {
state, reason = epistemics.FreshnessAssessmentStale, "valid-until elapsed"
}
if applicability.Volatility.HardStaleAfterMillis != nil && age > *applicability.Volatility.HardStaleAfterMillis {
state, reason = epistemics.FreshnessAssessmentStale, "hard volatility window elapsed"
}
if applicability.Volatility.RevalidateAfterMillis != nil && age > *applicability.Volatility.RevalidateAfterMillis && state == epistemics.FreshnessAssessmentCurrent {
state, reason = epistemics.FreshnessAssessmentAging, "revalidation window elapsed"
}
if maximumAgeMillis != nil && age > *maximumAgeMillis {
state, reason = epistemics.FreshnessAssessmentStale, "task maximum age exceeded"
}
if mode == "LIVE_REQUIRED" {
state, reason = epistemics.FreshnessAssessmentHistoricalOnly, "live source required"
}
return epistemics.FreshnessAssessment{SourceKnowledgeRef: "knowledge", TaskRef: "task", State: state, Reason: reason, AgeMillis: age, AssessedAtUnixMillis: nowMillis}
}
@@ -0,0 +1,17 @@
package domain_test
import (
"git.cin.su/m/Assistant/contracts/epistemics"
"git.cin.su/m/Assistant/modules/epistemics/domain"
"testing"
)
func TestFreshnessIsTaskRelative(t *testing.T) {
hard := int64(100)
app := epistemics.TemporalApplicability{ObservedAtUnixMillis: 1, Volatility: epistemics.VolatilitySpec{Mode: epistemics.VolatilityVersionBound, HardStaleAfterMillis: &hard}}
current := domain.AssessFreshness(app, "ANY", nil, 50)
historical := domain.AssessFreshness(app, "LIVE_REQUIRED", nil, 50)
if current.State != epistemics.FreshnessAssessmentCurrent || historical.State != epistemics.FreshnessAssessmentHistoricalOnly {
t.Fatalf("got %v and %v", current.State, historical.State)
}
}
+36
View File
@@ -0,0 +1,36 @@
package domain
import (
"errors"
"git.cin.su/m/Assistant/contracts/epistemics"
"git.cin.su/m/Assistant/platform/ids"
"strings"
)
var ErrInvalidKnowledge = errors.New("invalid epistemic knowledge record")
func ValidateProposition(value epistemics.Proposition) error {
if value.ID == "" || value.Kind == "" || strings.TrimSpace(value.SubjectRef) == "" || (value.ObjectValue == "" && value.ObjectRef == "" && value.TextFallback == "") {
return ErrInvalidKnowledge
}
return nil
}
func ValidateBeliefAssessment(value epistemics.BeliefAssessment) error {
if value.ID == "" || value.ClaimID == "" || !value.Revision.Valid() || value.State == "" || value.ConfidenceMillis < 0 || value.ConfidenceMillis > 1000 || value.AssessedAtUnixMillis < 1 {
return ErrInvalidKnowledge
}
return nil
}
func NewBeliefAssessment(claim epistemics.ClaimID, confidence int64, state epistemics.BeliefAssessmentState, evidence []epistemics.EvidenceRef, at int64) (epistemics.BeliefAssessment, error) {
id, err := ids.New()
if err != nil {
return epistemics.BeliefAssessment{}, err
}
value := epistemics.BeliefAssessment{ID: id, ClaimID: claim, Revision: ids.InitialRevision, State: state, ConfidenceMillis: confidence, EvidenceRefs: append([]epistemics.EvidenceRef(nil), evidence...), AssessedAtUnixMillis: at}
if err := ValidateBeliefAssessment(value); err != nil {
return epistemics.BeliefAssessment{}, err
}
return value, nil
}
@@ -0,0 +1,22 @@
package domain_test
import (
"git.cin.su/m/Assistant/contracts/epistemics"
"git.cin.su/m/Assistant/modules/epistemics/domain"
"testing"
)
func TestKnowledgeV2SeparatesPropositionAndReassessableBelief(t *testing.T) {
p := epistemics.Proposition{ID: "p", Kind: epistemics.PropositionWorldFacet, SubjectRef: "world:database:a", ObjectValue: "1.6.28"}
if err := domain.ValidateProposition(p); err != nil {
t.Fatal(err)
}
a, err := domain.NewBeliefAssessment("claim:a", 800, epistemics.BeliefAssessmentCurrent, []epistemics.EvidenceRef{"observation:a"}, 1)
if err != nil {
t.Fatal(err)
}
a.Revision++
if err := domain.ValidateBeliefAssessment(a); err != nil {
t.Fatal(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)
}
}
+17
View File
@@ -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")
}
}
+8
View File
@@ -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() }
+18
View File
@@ -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)
}
}
+86
View File
@@ -0,0 +1,86 @@
package domain
import (
"fmt"
contract "git.cin.su/m/Assistant/contracts/situation"
)
// FocusStack is a rebuildable, situation-owned projection. Push suspends the
// previous active frame; Pop resumes its parent and never deletes a frame.
type FocusStack struct{ frames []contract.FocusFrame }
func NewFocusStack(frames []contract.FocusFrame) (FocusStack, error) {
stack := FocusStack{frames: append([]contract.FocusFrame(nil), frames...)}
for _, frame := range stack.frames {
if err := frame.Validate(); err != nil {
return FocusStack{}, err
}
}
return stack, nil
}
func (s FocusStack) Frames() []contract.FocusFrame {
return append([]contract.FocusFrame(nil), s.frames...)
}
func (s FocusStack) Current() (contract.FocusFrame, error) {
for i := len(s.frames) - 1; i >= 0; i-- {
if s.frames[i].State == contract.FocusActive {
return s.frames[i], nil
}
}
return contract.FocusFrame{}, ErrNoActiveFocus
}
func (s FocusStack) Push(frame contract.FocusFrame) (FocusStack, error) {
if err := frame.Validate(); err != nil {
return FocusStack{}, err
}
if frame.State != contract.FocusActive {
return FocusStack{}, fmt.Errorf("pushed frame must be active")
}
frames := s.Frames()
if len(frames) > 0 {
current, err := s.Current()
if err == nil {
for i := range frames {
if frames[i].ID == current.ID {
frames[i].State = contract.FocusSuspended
break
}
}
frame.ParentFrameRef = &current.ID
}
}
frames = append(frames, frame)
return FocusStack{frames: frames}, nil
}
func (s FocusStack) Pop() (FocusStack, contract.FocusFrame, error) {
current, err := s.Current()
if err != nil {
return FocusStack{}, contract.FocusFrame{}, err
}
frames := s.Frames()
for i := range frames {
if frames[i].ID == current.ID {
frames[i].State = contract.FocusSuspended
break
}
}
if current.ParentFrameRef != nil {
for i := range frames {
if frames[i].ID == *current.ParentFrameRef {
frames[i].State = contract.FocusActive
break
}
}
}
return FocusStack{frames: frames}, current, nil
}
// ProjectFocusProjection retains the V1 API as a read projection only.
func ProjectFocusProjection(frame contract.FocusFrame, project contract.ProjectDescriptor) contract.ActiveProjectFocus {
return contract.ActiveProjectFocus{ActorID: frame.ActorID, PrincipalID: frame.PrincipalID, ProjectID: contract.ProjectID(project.ID), ProjectDisplayName: project.DisplayName, Provenance: contract.ProjectResolutionProvenance(frame.Provenance), ConfidenceMillis: frame.ConfidenceMillis, SourceUtteranceID: frame.SourceUtteranceRef, UpdatedAtUnixMillis: int64(frame.RecordedAt)}
}
+36
View File
@@ -0,0 +1,36 @@
package domain_test
import (
"testing"
contract "git.cin.su/m/Assistant/contracts/situation"
"git.cin.su/m/Assistant/modules/situation/domain"
)
func TestFocusStackPushPopKeepsParentAndSeparatesCompanies(t *testing.T) {
base := contract.FocusFrame{ID: "company-a", PrincipalID: "principal-a", ActorID: "actor", Revision: 1, ContextScopeRef: contract.SemanticReference{OwnerNamespace: "situation", SemanticKind: "context_scope", StableID: "scope-a"}, State: contract.FocusActive, Provenance: contract.FocusExplicitHuman, RecordedAt: 1}
stack, err := domain.NewFocusStack([]contract.FocusFrame{base})
if err != nil {
t.Fatal(err)
}
child := base
child.ID = "company-b"
child.PrincipalID = "principal-b"
child.ContextScopeRef.StableID = "scope-b"
stack, err = stack.Push(child)
if err != nil {
t.Fatal(err)
}
current, _ := stack.Current()
if current.ID != "company-b" || current.ParentFrameRef == nil || *current.ParentFrameRef != "company-a" {
t.Fatalf("unexpected current %#v", current)
}
stack, _, err = stack.Pop()
if err != nil {
t.Fatal(err)
}
current, _ = stack.Current()
if current.ID != "company-a" {
t.Fatalf("parent was not resumed: %#v", current)
}
}
+14
View File
@@ -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
}
+13
View File
@@ -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)
}
}
+18
View File
@@ -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
}
+16
View File
@@ -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)
}
}
+17
View File
@@ -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}
}
+17
View File
@@ -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)
}
}
+8
View File
@@ -0,0 +1,8 @@
# world
World owns typed referents, vocabulary and identity-resolution lineage. It
does not own observations, claims, beliefs, or factual values about a
referent. Those remain Epistemics-owned evidence.
World domain code does not import adapters, runtime or provider packages and
does not write another owner's canonical state.
+30
View File
@@ -0,0 +1,30 @@
package domain_test
import (
"testing"
"git.cin.su/m/Assistant/contracts/world"
"git.cin.su/m/Assistant/modules/world/domain"
)
func TestResolveCandidatesDoesNotAutoMergeAmbiguousPeopleOrSystems(t *testing.T) {
decision, candidates := domain.ResolveCandidates([]world.IdentityResolutionCandidate{
{ObjectRef: world.SemanticReference{OwnerNamespace: "world", SemanticKind: "person", StableID: "ivan-telegram"}, Confidence: 800},
{ObjectRef: world.SemanticReference{OwnerNamespace: "world", SemanticKind: "person", StableID: "ivan-crm"}, Confidence: 800},
}, 700)
if decision != world.ResolutionUnresolved || len(candidates) != 2 {
t.Fatalf("ambiguous result = %s, %#v", decision, candidates)
}
}
func TestVersionAndEnvironmentReferencesAreTyped(t *testing.T) {
version := world.SemanticReference{OwnerNamespace: "world", SemanticKind: "version", StableID: "unf-3"}
binding := world.VersionBinding{SubjectRef: world.SemanticReference{OwnerNamespace: "world", SemanticKind: "database", StableID: "company-a-unf"}, VersionRef: version, MatchMode: world.VersionExact}
if err := binding.Validate(); err != nil {
t.Fatal(err)
}
environment := world.EnvironmentReference{EnvironmentRef: world.SemanticReference{OwnerNamespace: "world", SemanticKind: "environment", StableID: "company-a-prod"}, VersionRef: &version}
if err := environment.Validate(); err != nil {
t.Fatal(err)
}
}
+34
View File
@@ -0,0 +1,34 @@
package domain
import "git.cin.su/m/Assistant/contracts/world"
import "sort"
func ValidateObject(value world.WorldObject) error { return value.Validate() }
func ValidateKindDefinition(value world.WorldObjectKindDefinition) error { return value.Validate() }
func ValidateAlias(value world.WorldAlias) error { return value.Validate() }
func ValidateFacetDefinition(value world.FacetDefinition) error { return value.Validate() }
func ValidateRelationDefinition(value world.RelationDefinition) error { return value.Validate() }
func ValidateResolution(value world.IdentityResolutionDecisionRecord) error { return value.Validate() }
func ValidateLineage(value world.WorldLineage) error { return value.Validate() }
// ResolveCandidates deliberately refuses to merge an ambiguous result. A
// caller may persist the returned UNRESOLVED decision and later re-evaluate it
// with additional evidence.
func ResolveCandidates(candidates []world.IdentityResolutionCandidate, minimumConfidence int64) (world.ResolutionDecision, []world.IdentityResolutionCandidate) {
ordered := append([]world.IdentityResolutionCandidate(nil), candidates...)
sort.SliceStable(ordered, func(i, j int) bool { return ordered[i].Confidence > ordered[j].Confidence })
if len(ordered) == 0 || ordered[0].Confidence < minimumConfidence {
return world.ResolutionUnresolved, ordered
}
if len(ordered) > 1 && ordered[0].Confidence == ordered[1].Confidence {
return world.ResolutionUnresolved, ordered
}
return world.ResolutionSame, ordered[:1]
}
+17
View File
@@ -0,0 +1,17 @@
package ports
import (
"context"
"git.cin.su/m/Assistant/contracts/world"
)
type Repository interface {
SaveKindDefinition(context.Context, world.WorldObjectKindDefinition) error
SaveObject(context.Context, world.WorldObject) error
SaveAlias(context.Context, world.WorldAlias) error
SaveFacetDefinition(context.Context, world.FacetDefinition) error
SaveRelationDefinition(context.Context, world.RelationDefinition) error
SaveResolution(context.Context, world.IdentityResolutionDecisionRecord) error
SaveLineage(context.Context, world.WorldLineage) error
}
+14
View File
@@ -0,0 +1,14 @@
package clock
import "time"
// Instant is a UTC point represented as Unix milliseconds.
type Instant int64
func (i Instant) Valid() bool { return i > 0 }
func NowInstant() Instant { return FromTime(time.Now().UTC()) }
func FromTime(value time.Time) Instant { return Instant(value.UTC().UnixMilli()) }
func (i Instant) Time() time.Time { return time.UnixMilli(int64(i)).UTC() }
+14
View File
@@ -0,0 +1,14 @@
package clock
import (
"testing"
"time"
)
func TestInstantRoundTripUsesUTCUnixMilliseconds(t *testing.T) {
want := time.Date(2026, time.August, 29, 12, 34, 56, 789000000, time.FixedZone("local", 3*60*60))
got := FromTime(want).Time()
if !got.Equal(want.UTC()) || got.Location() != time.UTC {
t.Fatalf("instant round trip = %v, want %v UTC", got, want.UTC())
}
}
+34 -5
View File
@@ -6,14 +6,43 @@ import (
"fmt"
)
// ID is a transport-neutral opaque identifier primitive. Domain packages wrap it
// in strong semantic ID types; do not pass bare ID across semantic boundaries.
type ID string
// StableID is a transport-neutral opaque identifier primitive. Domain packages
// wrap it in strong semantic ID types; do not pass bare StableID across
// semantic boundaries.
type StableID string
func New() (ID, error) {
// ID is retained as a compatibility name for the V1 primitive.
type ID = StableID
// Revision is the optimistic version of a versioned semantic record.
type Revision uint64
const InitialRevision Revision = 1
func (r Revision) Valid() bool { return r >= InitialRevision }
// SemanticRef is a technical cross-owner reference envelope. It identifies a
// record but does not grant storage ownership or provide generic CRUD.
type SemanticRef struct {
OwnerNamespace string
SemanticKind string
StableID StableID
Revision *Revision
}
func (r SemanticRef) Valid() bool {
return r.OwnerNamespace != "" && r.SemanticKind != "" && r.StableID != "" &&
(r.Revision == nil || r.Revision.Valid())
}
func NewStableID() (StableID, error) {
var b [16]byte
if _, err := rand.Read(b[:]); err != nil {
return "", fmt.Errorf("generate id: %w", err)
}
return ID(hex.EncodeToString(b[:])), nil
return StableID(hex.EncodeToString(b[:])), nil
}
func New() (ID, error) {
return NewStableID()
}
+21
View File
@@ -0,0 +1,21 @@
package ids
import "testing"
func TestNewStableIDIsOpaque128BitHex(t *testing.T) {
id, err := NewStableID()
if err != nil || len(id) != 32 {
t.Fatalf("NewStableID() = %q, %v", id, err)
}
if !(SemanticRef{OwnerNamespace: "world", SemanticKind: "object", StableID: id}.Valid()) {
t.Fatal("stable id was not accepted by semantic reference")
}
}
func TestSemanticRefRejectsInvalidRevision(t *testing.T) {
revision := Revision(0)
ref := SemanticRef{OwnerNamespace: "world", SemanticKind: "object", StableID: "id", Revision: &revision}
if ref.Valid() {
t.Fatal("semantic reference accepted invalid revision")
}
}
+7
View File
@@ -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 != ""
}
+92
View File
@@ -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
}
+14
View File
@@ -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)
}
}
+62
View File
@@ -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
}
+17
View File
@@ -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)
}
}
+18
View File
@@ -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")
}
}