Align SLURP access control with config authority levels
This commit is contained in:
@@ -274,14 +274,13 @@ func (c *Config) ApplyRoleDefinition(role string) error {
|
||||
}
|
||||
|
||||
// GetRoleAuthority returns the authority level for a role (from CHORUS)
|
||||
func (c *Config) GetRoleAuthority(role string) (string, error) {
|
||||
// This would contain the authority mapping from CHORUS
|
||||
switch role {
|
||||
case "admin":
|
||||
return "master", nil
|
||||
default:
|
||||
return "member", nil
|
||||
func (c *Config) GetRoleAuthority(role string) (AuthorityLevel, error) {
|
||||
roles := GetPredefinedRoles()
|
||||
if def, ok := roles[role]; ok {
|
||||
return def.AuthorityLevel, nil
|
||||
}
|
||||
|
||||
return AuthorityReadOnly, fmt.Errorf("unknown role: %s", role)
|
||||
}
|
||||
|
||||
// Helper functions for environment variable parsing
|
||||
|
||||
@@ -2,12 +2,18 @@ package config
|
||||
|
||||
import "time"
|
||||
|
||||
// Authority levels for roles
|
||||
// AuthorityLevel represents the privilege tier associated with a role.
|
||||
type AuthorityLevel string
|
||||
|
||||
// Authority levels for roles (aligned with CHORUS hierarchy).
|
||||
const (
|
||||
AuthorityReadOnly = "readonly"
|
||||
AuthoritySuggestion = "suggestion"
|
||||
AuthorityFull = "full"
|
||||
AuthorityAdmin = "admin"
|
||||
AuthorityMaster AuthorityLevel = "master"
|
||||
AuthorityAdmin AuthorityLevel = "admin"
|
||||
AuthorityDecision AuthorityLevel = "decision"
|
||||
AuthorityCoordination AuthorityLevel = "coordination"
|
||||
AuthorityFull AuthorityLevel = "full"
|
||||
AuthoritySuggestion AuthorityLevel = "suggestion"
|
||||
AuthorityReadOnly AuthorityLevel = "readonly"
|
||||
)
|
||||
|
||||
// SecurityConfig defines security-related configuration
|
||||
@@ -43,14 +49,14 @@ type AgeKeyPair struct {
|
||||
|
||||
// RoleDefinition represents a role configuration
|
||||
type RoleDefinition struct {
|
||||
Name string `yaml:"name"`
|
||||
Description string `yaml:"description"`
|
||||
Capabilities []string `yaml:"capabilities"`
|
||||
AccessLevel string `yaml:"access_level"`
|
||||
AuthorityLevel string `yaml:"authority_level"`
|
||||
Keys *AgeKeyPair `yaml:"keys,omitempty"`
|
||||
AgeKeys *AgeKeyPair `yaml:"age_keys,omitempty"` // Legacy field name
|
||||
CanDecrypt []string `yaml:"can_decrypt,omitempty"` // Roles this role can decrypt
|
||||
Name string `yaml:"name"`
|
||||
Description string `yaml:"description"`
|
||||
Capabilities []string `yaml:"capabilities"`
|
||||
AccessLevel string `yaml:"access_level"`
|
||||
AuthorityLevel AuthorityLevel `yaml:"authority_level"`
|
||||
Keys *AgeKeyPair `yaml:"keys,omitempty"`
|
||||
AgeKeys *AgeKeyPair `yaml:"age_keys,omitempty"` // Legacy field name
|
||||
CanDecrypt []string `yaml:"can_decrypt,omitempty"` // Roles this role can decrypt
|
||||
}
|
||||
|
||||
// GetPredefinedRoles returns the predefined roles for the system
|
||||
@@ -61,7 +67,7 @@ func GetPredefinedRoles() map[string]*RoleDefinition {
|
||||
Description: "Project coordination and management",
|
||||
Capabilities: []string{"coordination", "planning", "oversight"},
|
||||
AccessLevel: "high",
|
||||
AuthorityLevel: AuthorityAdmin,
|
||||
AuthorityLevel: AuthorityMaster,
|
||||
CanDecrypt: []string{"project_manager", "backend_developer", "frontend_developer", "devops_engineer", "security_engineer"},
|
||||
},
|
||||
"backend_developer": {
|
||||
@@ -69,7 +75,7 @@ func GetPredefinedRoles() map[string]*RoleDefinition {
|
||||
Description: "Backend development and API work",
|
||||
Capabilities: []string{"backend", "api", "database"},
|
||||
AccessLevel: "medium",
|
||||
AuthorityLevel: AuthorityFull,
|
||||
AuthorityLevel: AuthorityDecision,
|
||||
CanDecrypt: []string{"backend_developer"},
|
||||
},
|
||||
"frontend_developer": {
|
||||
@@ -77,7 +83,7 @@ func GetPredefinedRoles() map[string]*RoleDefinition {
|
||||
Description: "Frontend UI development",
|
||||
Capabilities: []string{"frontend", "ui", "components"},
|
||||
AccessLevel: "medium",
|
||||
AuthorityLevel: AuthorityFull,
|
||||
AuthorityLevel: AuthorityCoordination,
|
||||
CanDecrypt: []string{"frontend_developer"},
|
||||
},
|
||||
"devops_engineer": {
|
||||
@@ -85,7 +91,7 @@ func GetPredefinedRoles() map[string]*RoleDefinition {
|
||||
Description: "Infrastructure and deployment",
|
||||
Capabilities: []string{"infrastructure", "deployment", "monitoring"},
|
||||
AccessLevel: "high",
|
||||
AuthorityLevel: AuthorityFull,
|
||||
AuthorityLevel: AuthorityDecision,
|
||||
CanDecrypt: []string{"devops_engineer", "backend_developer"},
|
||||
},
|
||||
"security_engineer": {
|
||||
@@ -93,7 +99,7 @@ func GetPredefinedRoles() map[string]*RoleDefinition {
|
||||
Description: "Security oversight and hardening",
|
||||
Capabilities: []string{"security", "audit", "compliance"},
|
||||
AccessLevel: "high",
|
||||
AuthorityLevel: AuthorityAdmin,
|
||||
AuthorityLevel: AuthorityMaster,
|
||||
CanDecrypt: []string{"security_engineer", "project_manager", "backend_developer", "frontend_developer", "devops_engineer"},
|
||||
},
|
||||
"security_expert": {
|
||||
@@ -101,7 +107,7 @@ func GetPredefinedRoles() map[string]*RoleDefinition {
|
||||
Description: "Advanced security analysis and policy work",
|
||||
Capabilities: []string{"security", "policy", "response"},
|
||||
AccessLevel: "high",
|
||||
AuthorityLevel: AuthorityAdmin,
|
||||
AuthorityLevel: AuthorityMaster,
|
||||
CanDecrypt: []string{"security_expert", "security_engineer", "project_manager"},
|
||||
},
|
||||
"senior_software_architect": {
|
||||
@@ -109,7 +115,7 @@ func GetPredefinedRoles() map[string]*RoleDefinition {
|
||||
Description: "Architecture governance and system design",
|
||||
Capabilities: []string{"architecture", "design", "coordination"},
|
||||
AccessLevel: "high",
|
||||
AuthorityLevel: AuthorityAdmin,
|
||||
AuthorityLevel: AuthorityDecision,
|
||||
CanDecrypt: []string{"senior_software_architect", "project_manager", "backend_developer", "frontend_developer"},
|
||||
},
|
||||
"qa_engineer": {
|
||||
@@ -117,7 +123,7 @@ func GetPredefinedRoles() map[string]*RoleDefinition {
|
||||
Description: "Quality assurance and testing",
|
||||
Capabilities: []string{"testing", "validation"},
|
||||
AccessLevel: "medium",
|
||||
AuthorityLevel: AuthorityFull,
|
||||
AuthorityLevel: AuthorityCoordination,
|
||||
CanDecrypt: []string{"qa_engineer", "backend_developer", "frontend_developer"},
|
||||
},
|
||||
"readonly_user": {
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"chorus/pkg/ucxl"
|
||||
"chorus/pkg/config"
|
||||
"chorus/pkg/ucxl"
|
||||
)
|
||||
|
||||
// ContextNode represents a hierarchical context node in the SLURP system.
|
||||
@@ -19,25 +19,25 @@ type ContextNode struct {
|
||||
UCXLAddress ucxl.Address `json:"ucxl_address"` // Associated UCXL address
|
||||
Summary string `json:"summary"` // Brief description
|
||||
Purpose string `json:"purpose"` // What this component does
|
||||
|
||||
|
||||
// Context metadata
|
||||
Technologies []string `json:"technologies"` // Technologies used
|
||||
Tags []string `json:"tags"` // Categorization tags
|
||||
Insights []string `json:"insights"` // Analytical insights
|
||||
|
||||
|
||||
// Hierarchy control
|
||||
OverridesParent bool `json:"overrides_parent"` // Whether this overrides parent context
|
||||
ContextSpecificity int `json:"context_specificity"` // Specificity level (higher = more specific)
|
||||
AppliesToChildren bool `json:"applies_to_children"` // Whether this applies to child directories
|
||||
|
||||
OverridesParent bool `json:"overrides_parent"` // Whether this overrides parent context
|
||||
ContextSpecificity int `json:"context_specificity"` // Specificity level (higher = more specific)
|
||||
AppliesToChildren bool `json:"applies_to_children"` // Whether this applies to child directories
|
||||
|
||||
// Metadata
|
||||
GeneratedAt time.Time `json:"generated_at"` // When context was generated
|
||||
RAGConfidence float64 `json:"rag_confidence"` // RAG system confidence (0-1)
|
||||
|
||||
|
||||
// Access control
|
||||
EncryptedFor []string `json:"encrypted_for"` // Roles that can access
|
||||
AccessLevel RoleAccessLevel `json:"access_level"` // Required access level
|
||||
|
||||
EncryptedFor []string `json:"encrypted_for"` // Roles that can access
|
||||
AccessLevel RoleAccessLevel `json:"access_level"` // Required access level
|
||||
|
||||
// Custom metadata
|
||||
Metadata map[string]interface{} `json:"metadata,omitempty"` // Additional metadata
|
||||
}
|
||||
@@ -47,11 +47,11 @@ type ContextNode struct {
|
||||
type RoleAccessLevel int
|
||||
|
||||
const (
|
||||
AccessPublic RoleAccessLevel = iota // Anyone can access
|
||||
AccessLow // Basic role access
|
||||
AccessMedium // Coordination role access
|
||||
AccessHigh // Decision role access
|
||||
AccessCritical // Master role access only
|
||||
AccessPublic RoleAccessLevel = iota // Anyone can access
|
||||
AccessLow // Basic role access
|
||||
AccessMedium // Coordination role access
|
||||
AccessHigh // Decision role access
|
||||
AccessCritical // Master role access only
|
||||
)
|
||||
|
||||
// EncryptedContext represents role-encrypted context data for DHT storage
|
||||
@@ -75,26 +75,26 @@ type ResolvedContext struct {
|
||||
Technologies []string `json:"technologies"` // Merged technologies
|
||||
Tags []string `json:"tags"` // Merged tags
|
||||
Insights []string `json:"insights"` // Merged insights
|
||||
|
||||
|
||||
// Resolution metadata
|
||||
ContextSourcePath string `json:"context_source_path"` // Primary source context path
|
||||
InheritanceChain []string `json:"inheritance_chain"` // Context inheritance chain
|
||||
ResolutionConfidence float64 `json:"resolution_confidence"` // Overall confidence (0-1)
|
||||
BoundedDepth int `json:"bounded_depth"` // Actual traversal depth used
|
||||
GlobalContextsApplied bool `json:"global_contexts_applied"` // Whether global contexts were applied
|
||||
ResolvedAt time.Time `json:"resolved_at"` // When resolution occurred
|
||||
ContextSourcePath string `json:"context_source_path"` // Primary source context path
|
||||
InheritanceChain []string `json:"inheritance_chain"` // Context inheritance chain
|
||||
ResolutionConfidence float64 `json:"resolution_confidence"` // Overall confidence (0-1)
|
||||
BoundedDepth int `json:"bounded_depth"` // Actual traversal depth used
|
||||
GlobalContextsApplied bool `json:"global_contexts_applied"` // Whether global contexts were applied
|
||||
ResolvedAt time.Time `json:"resolved_at"` // When resolution occurred
|
||||
}
|
||||
|
||||
// ResolutionStatistics represents statistics about context resolution operations
|
||||
type ResolutionStatistics struct {
|
||||
ContextNodes int `json:"context_nodes"` // Total context nodes in hierarchy
|
||||
GlobalContexts int `json:"global_contexts"` // Number of global contexts
|
||||
MaxHierarchyDepth int `json:"max_hierarchy_depth"` // Maximum hierarchy depth allowed
|
||||
CachedResolutions int `json:"cached_resolutions"` // Number of cached resolutions
|
||||
TotalResolutions int `json:"total_resolutions"` // Total resolution operations
|
||||
AverageDepth float64 `json:"average_depth"` // Average traversal depth
|
||||
CacheHitRate float64 `json:"cache_hit_rate"` // Cache hit rate (0-1)
|
||||
LastResetAt time.Time `json:"last_reset_at"` // When stats were last reset
|
||||
ContextNodes int `json:"context_nodes"` // Total context nodes in hierarchy
|
||||
GlobalContexts int `json:"global_contexts"` // Number of global contexts
|
||||
MaxHierarchyDepth int `json:"max_hierarchy_depth"` // Maximum hierarchy depth allowed
|
||||
CachedResolutions int `json:"cached_resolutions"` // Number of cached resolutions
|
||||
TotalResolutions int `json:"total_resolutions"` // Total resolution operations
|
||||
AverageDepth float64 `json:"average_depth"` // Average traversal depth
|
||||
CacheHitRate float64 `json:"cache_hit_rate"` // Cache hit rate (0-1)
|
||||
LastResetAt time.Time `json:"last_reset_at"` // When stats were last reset
|
||||
}
|
||||
|
||||
// ContextScope defines the scope of a context node's application
|
||||
@@ -108,25 +108,25 @@ const (
|
||||
|
||||
// HierarchyStats represents statistics about hierarchy operations
|
||||
type HierarchyStats struct {
|
||||
NodesCreated int `json:"nodes_created"` // Number of nodes created
|
||||
NodesUpdated int `json:"nodes_updated"` // Number of nodes updated
|
||||
FilesAnalyzed int `json:"files_analyzed"` // Number of files analyzed
|
||||
DirectoriesScanned int `json:"directories_scanned"` // Number of directories scanned
|
||||
GenerationTime time.Duration `json:"generation_time"` // Time taken for generation
|
||||
AverageConfidence float64 `json:"average_confidence"` // Average confidence score
|
||||
TotalSize int64 `json:"total_size"` // Total size of analyzed content
|
||||
SkippedFiles int `json:"skipped_files"` // Number of files skipped
|
||||
Errors []string `json:"errors"` // Generation errors
|
||||
NodesCreated int `json:"nodes_created"` // Number of nodes created
|
||||
NodesUpdated int `json:"nodes_updated"` // Number of nodes updated
|
||||
FilesAnalyzed int `json:"files_analyzed"` // Number of files analyzed
|
||||
DirectoriesScanned int `json:"directories_scanned"` // Number of directories scanned
|
||||
GenerationTime time.Duration `json:"generation_time"` // Time taken for generation
|
||||
AverageConfidence float64 `json:"average_confidence"` // Average confidence score
|
||||
TotalSize int64 `json:"total_size"` // Total size of analyzed content
|
||||
SkippedFiles int `json:"skipped_files"` // Number of files skipped
|
||||
Errors []string `json:"errors"` // Generation errors
|
||||
}
|
||||
|
||||
// CacheEntry represents a cached context resolution
|
||||
type CacheEntry struct {
|
||||
Key string `json:"key"` // Cache key
|
||||
ResolvedCtx *ResolvedContext `json:"resolved_ctx"` // Cached resolved context
|
||||
CreatedAt time.Time `json:"created_at"` // When cached
|
||||
ExpiresAt time.Time `json:"expires_at"` // When cache expires
|
||||
AccessCount int `json:"access_count"` // Number of times accessed
|
||||
LastAccessed time.Time `json:"last_accessed"` // When last accessed
|
||||
Key string `json:"key"` // Cache key
|
||||
ResolvedCtx *ResolvedContext `json:"resolved_ctx"` // Cached resolved context
|
||||
CreatedAt time.Time `json:"created_at"` // When cached
|
||||
ExpiresAt time.Time `json:"expires_at"` // When cache expires
|
||||
AccessCount int `json:"access_count"` // Number of times accessed
|
||||
LastAccessed time.Time `json:"last_accessed"` // When last accessed
|
||||
}
|
||||
|
||||
// ValidationResult represents the result of context validation
|
||||
@@ -149,13 +149,13 @@ type ValidationIssue struct {
|
||||
|
||||
// MergeOptions defines options for merging contexts during resolution
|
||||
type MergeOptions struct {
|
||||
PreferParent bool `json:"prefer_parent"` // Prefer parent values over child
|
||||
MergeTechnologies bool `json:"merge_technologies"` // Merge technology lists
|
||||
MergeTags bool `json:"merge_tags"` // Merge tag lists
|
||||
MergeInsights bool `json:"merge_insights"` // Merge insight lists
|
||||
ExcludedFields []string `json:"excluded_fields"` // Fields to exclude from merge
|
||||
WeightParentByDepth bool `json:"weight_parent_by_depth"` // Weight parent influence by depth
|
||||
MinConfidenceThreshold float64 `json:"min_confidence_threshold"` // Minimum confidence to include
|
||||
PreferParent bool `json:"prefer_parent"` // Prefer parent values over child
|
||||
MergeTechnologies bool `json:"merge_technologies"` // Merge technology lists
|
||||
MergeTags bool `json:"merge_tags"` // Merge tag lists
|
||||
MergeInsights bool `json:"merge_insights"` // Merge insight lists
|
||||
ExcludedFields []string `json:"excluded_fields"` // Fields to exclude from merge
|
||||
WeightParentByDepth bool `json:"weight_parent_by_depth"` // Weight parent influence by depth
|
||||
MinConfidenceThreshold float64 `json:"min_confidence_threshold"` // Minimum confidence to include
|
||||
}
|
||||
|
||||
// BatchResolutionRequest represents a batch resolution request
|
||||
@@ -178,12 +178,12 @@ type BatchResolutionResult struct {
|
||||
|
||||
// ContextError represents a context-related error with structured information
|
||||
type ContextError struct {
|
||||
Type string `json:"type"` // Error type (validation, resolution, access, etc.)
|
||||
Message string `json:"message"` // Human-readable error message
|
||||
Code string `json:"code"` // Machine-readable error code
|
||||
Address *ucxl.Address `json:"address"` // Related UCXL address if applicable
|
||||
Context map[string]string `json:"context"` // Additional context information
|
||||
Underlying error `json:"underlying"` // Underlying error if any
|
||||
Type string `json:"type"` // Error type (validation, resolution, access, etc.)
|
||||
Message string `json:"message"` // Human-readable error message
|
||||
Code string `json:"code"` // Machine-readable error code
|
||||
Address *ucxl.Address `json:"address"` // Related UCXL address if applicable
|
||||
Context map[string]string `json:"context"` // Additional context information
|
||||
Underlying error `json:"underlying"` // Underlying error if any
|
||||
}
|
||||
|
||||
func (e *ContextError) Error() string {
|
||||
@@ -199,34 +199,34 @@ func (e *ContextError) Unwrap() error {
|
||||
|
||||
// Common error types and codes
|
||||
const (
|
||||
ErrorTypeValidation = "validation"
|
||||
ErrorTypeResolution = "resolution"
|
||||
ErrorTypeAccess = "access"
|
||||
ErrorTypeStorage = "storage"
|
||||
ErrorTypeEncryption = "encryption"
|
||||
ErrorTypeDHT = "dht"
|
||||
ErrorTypeHierarchy = "hierarchy"
|
||||
ErrorTypeCache = "cache"
|
||||
ErrorTypeTemporalGraph = "temporal_graph"
|
||||
ErrorTypeIntelligence = "intelligence"
|
||||
ErrorTypeValidation = "validation"
|
||||
ErrorTypeResolution = "resolution"
|
||||
ErrorTypeAccess = "access"
|
||||
ErrorTypeStorage = "storage"
|
||||
ErrorTypeEncryption = "encryption"
|
||||
ErrorTypeDHT = "dht"
|
||||
ErrorTypeHierarchy = "hierarchy"
|
||||
ErrorTypeCache = "cache"
|
||||
ErrorTypeTemporalGraph = "temporal_graph"
|
||||
ErrorTypeIntelligence = "intelligence"
|
||||
)
|
||||
|
||||
const (
|
||||
ErrorCodeInvalidAddress = "invalid_address"
|
||||
ErrorCodeInvalidContext = "invalid_context"
|
||||
ErrorCodeInvalidRole = "invalid_role"
|
||||
ErrorCodeAccessDenied = "access_denied"
|
||||
ErrorCodeNotFound = "not_found"
|
||||
ErrorCodeDepthExceeded = "depth_exceeded"
|
||||
ErrorCodeCycleDetected = "cycle_detected"
|
||||
ErrorCodeEncryptionFailed = "encryption_failed"
|
||||
ErrorCodeDecryptionFailed = "decryption_failed"
|
||||
ErrorCodeDHTError = "dht_error"
|
||||
ErrorCodeCacheError = "cache_error"
|
||||
ErrorCodeStorageError = "storage_error"
|
||||
ErrorCodeInvalidConfig = "invalid_config"
|
||||
ErrorCodeTimeout = "timeout"
|
||||
ErrorCodeInternalError = "internal_error"
|
||||
ErrorCodeInvalidAddress = "invalid_address"
|
||||
ErrorCodeInvalidContext = "invalid_context"
|
||||
ErrorCodeInvalidRole = "invalid_role"
|
||||
ErrorCodeAccessDenied = "access_denied"
|
||||
ErrorCodeNotFound = "not_found"
|
||||
ErrorCodeDepthExceeded = "depth_exceeded"
|
||||
ErrorCodeCycleDetected = "cycle_detected"
|
||||
ErrorCodeEncryptionFailed = "encryption_failed"
|
||||
ErrorCodeDecryptionFailed = "decryption_failed"
|
||||
ErrorCodeDHTError = "dht_error"
|
||||
ErrorCodeCacheError = "cache_error"
|
||||
ErrorCodeStorageError = "storage_error"
|
||||
ErrorCodeInvalidConfig = "invalid_config"
|
||||
ErrorCodeTimeout = "timeout"
|
||||
ErrorCodeInternalError = "internal_error"
|
||||
)
|
||||
|
||||
// NewContextError creates a new context error with structured information
|
||||
@@ -292,7 +292,7 @@ func ParseRoleAccessLevel(level string) (RoleAccessLevel, error) {
|
||||
case "critical":
|
||||
return AccessCritical, nil
|
||||
default:
|
||||
return AccessPublic, NewContextError(ErrorTypeValidation, ErrorCodeInvalidRole,
|
||||
return AccessPublic, NewContextError(ErrorTypeValidation, ErrorCodeInvalidRole,
|
||||
fmt.Sprintf("invalid role access level: %s", level))
|
||||
}
|
||||
}
|
||||
@@ -302,8 +302,12 @@ func AuthorityToAccessLevel(authority config.AuthorityLevel) RoleAccessLevel {
|
||||
switch authority {
|
||||
case config.AuthorityMaster:
|
||||
return AccessCritical
|
||||
case config.AuthorityAdmin:
|
||||
return AccessCritical
|
||||
case config.AuthorityDecision:
|
||||
return AccessHigh
|
||||
case config.AuthorityFull:
|
||||
return AccessHigh
|
||||
case config.AuthorityCoordination:
|
||||
return AccessMedium
|
||||
case config.AuthoritySuggestion:
|
||||
@@ -322,23 +326,23 @@ func (cn *ContextNode) Validate() error {
|
||||
}
|
||||
|
||||
if err := cn.UCXLAddress.Validate(); err != nil {
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidAddress,
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidAddress,
|
||||
"invalid UCXL address").WithUnderlying(err).WithAddress(cn.UCXLAddress)
|
||||
}
|
||||
|
||||
if cn.Summary == "" {
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidContext,
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidContext,
|
||||
"context summary cannot be empty").WithAddress(cn.UCXLAddress)
|
||||
}
|
||||
|
||||
if cn.RAGConfidence < 0 || cn.RAGConfidence > 1 {
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidContext,
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidContext,
|
||||
"RAG confidence must be between 0 and 1").WithAddress(cn.UCXLAddress).
|
||||
WithContext("confidence", fmt.Sprintf("%.2f", cn.RAGConfidence))
|
||||
}
|
||||
|
||||
if cn.ContextSpecificity < 0 {
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidContext,
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidContext,
|
||||
"context specificity cannot be negative").WithAddress(cn.UCXLAddress).
|
||||
WithContext("specificity", fmt.Sprintf("%d", cn.ContextSpecificity))
|
||||
}
|
||||
@@ -346,7 +350,7 @@ func (cn *ContextNode) Validate() error {
|
||||
// Validate role access levels
|
||||
for _, role := range cn.EncryptedFor {
|
||||
if role == "" {
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidRole,
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidRole,
|
||||
"encrypted_for roles cannot be empty").WithAddress(cn.UCXLAddress)
|
||||
}
|
||||
}
|
||||
@@ -354,32 +358,32 @@ func (cn *ContextNode) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate validates a ResolvedContext for consistency and completeness
|
||||
// Validate validates a ResolvedContext for consistency and completeness
|
||||
func (rc *ResolvedContext) Validate() error {
|
||||
if err := rc.UCXLAddress.Validate(); err != nil {
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidAddress,
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidAddress,
|
||||
"invalid UCXL address in resolved context").WithUnderlying(err).WithAddress(rc.UCXLAddress)
|
||||
}
|
||||
|
||||
if rc.Summary == "" {
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidContext,
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidContext,
|
||||
"resolved context summary cannot be empty").WithAddress(rc.UCXLAddress)
|
||||
}
|
||||
|
||||
if rc.ResolutionConfidence < 0 || rc.ResolutionConfidence > 1 {
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidContext,
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidContext,
|
||||
"resolution confidence must be between 0 and 1").WithAddress(rc.UCXLAddress).
|
||||
WithContext("confidence", fmt.Sprintf("%.2f", rc.ResolutionConfidence))
|
||||
}
|
||||
|
||||
if rc.BoundedDepth < 0 {
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidContext,
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidContext,
|
||||
"bounded depth cannot be negative").WithAddress(rc.UCXLAddress).
|
||||
WithContext("depth", fmt.Sprintf("%d", rc.BoundedDepth))
|
||||
}
|
||||
|
||||
if rc.ContextSourcePath == "" {
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidContext,
|
||||
return NewContextError(ErrorTypeValidation, ErrorCodeInvalidContext,
|
||||
"context source path cannot be empty").WithAddress(rc.UCXLAddress)
|
||||
}
|
||||
|
||||
@@ -398,8 +402,8 @@ func (cn *ContextNode) HasRole(role string) bool {
|
||||
|
||||
// CanAccess checks if a role can access this context based on authority level
|
||||
func (cn *ContextNode) CanAccess(role string, authority config.AuthorityLevel) bool {
|
||||
// Master authority can access everything
|
||||
if authority == config.AuthorityMaster {
|
||||
// Master/Admin authority can access everything
|
||||
if authority == config.AuthorityMaster || authority == config.AuthorityAdmin {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -421,16 +425,16 @@ func (cn *ContextNode) Clone() *ContextNode {
|
||||
Summary: cn.Summary,
|
||||
Purpose: cn.Purpose,
|
||||
Technologies: make([]string, len(cn.Technologies)),
|
||||
Tags: make([]string, len(cn.Tags)),
|
||||
Insights: make([]string, len(cn.Insights)),
|
||||
OverridesParent: cn.OverridesParent,
|
||||
Tags: make([]string, len(cn.Tags)),
|
||||
Insights: make([]string, len(cn.Insights)),
|
||||
OverridesParent: cn.OverridesParent,
|
||||
ContextSpecificity: cn.ContextSpecificity,
|
||||
AppliesToChildren: cn.AppliesToChildren,
|
||||
GeneratedAt: cn.GeneratedAt,
|
||||
RAGConfidence: cn.RAGConfidence,
|
||||
EncryptedFor: make([]string, len(cn.EncryptedFor)),
|
||||
AccessLevel: cn.AccessLevel,
|
||||
Metadata: make(map[string]interface{}),
|
||||
AppliesToChildren: cn.AppliesToChildren,
|
||||
GeneratedAt: cn.GeneratedAt,
|
||||
RAGConfidence: cn.RAGConfidence,
|
||||
EncryptedFor: make([]string, len(cn.EncryptedFor)),
|
||||
AccessLevel: cn.AccessLevel,
|
||||
Metadata: make(map[string]interface{}),
|
||||
}
|
||||
|
||||
copy(cloned.Technologies, cn.Technologies)
|
||||
@@ -448,18 +452,18 @@ func (cn *ContextNode) Clone() *ContextNode {
|
||||
// Clone creates a deep copy of the ResolvedContext
|
||||
func (rc *ResolvedContext) Clone() *ResolvedContext {
|
||||
cloned := &ResolvedContext{
|
||||
UCXLAddress: *rc.UCXLAddress.Clone(),
|
||||
Summary: rc.Summary,
|
||||
Purpose: rc.Purpose,
|
||||
Technologies: make([]string, len(rc.Technologies)),
|
||||
Tags: make([]string, len(rc.Tags)),
|
||||
Insights: make([]string, len(rc.Insights)),
|
||||
ContextSourcePath: rc.ContextSourcePath,
|
||||
InheritanceChain: make([]string, len(rc.InheritanceChain)),
|
||||
ResolutionConfidence: rc.ResolutionConfidence,
|
||||
BoundedDepth: rc.BoundedDepth,
|
||||
GlobalContextsApplied: rc.GlobalContextsApplied,
|
||||
ResolvedAt: rc.ResolvedAt,
|
||||
UCXLAddress: *rc.UCXLAddress.Clone(),
|
||||
Summary: rc.Summary,
|
||||
Purpose: rc.Purpose,
|
||||
Technologies: make([]string, len(rc.Technologies)),
|
||||
Tags: make([]string, len(rc.Tags)),
|
||||
Insights: make([]string, len(rc.Insights)),
|
||||
ContextSourcePath: rc.ContextSourcePath,
|
||||
InheritanceChain: make([]string, len(rc.InheritanceChain)),
|
||||
ResolutionConfidence: rc.ResolutionConfidence,
|
||||
BoundedDepth: rc.BoundedDepth,
|
||||
GlobalContextsApplied: rc.GlobalContextsApplied,
|
||||
ResolvedAt: rc.ResolvedAt,
|
||||
}
|
||||
|
||||
copy(cloned.Technologies, rc.Technologies)
|
||||
@@ -468,4 +472,4 @@ func (rc *ResolvedContext) Clone() *ResolvedContext {
|
||||
copy(cloned.InheritanceChain, rc.InheritanceChain)
|
||||
|
||||
return cloned
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user