Files
2026-08-29 02:17:36 +03:00

142 lines
4.5 KiB
Go

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
}