This comprehensive refactoring addresses critical architectural issues: IMPORT CYCLE RESOLUTION: • pkg/crypto ↔ pkg/slurp/roles: Created pkg/security/access_levels.go • pkg/ucxl → pkg/dht: Created pkg/storage/interfaces.go • pkg/slurp/leader → pkg/election → pkg/slurp/storage: Moved types to pkg/election/interfaces.go MODULE PATH MIGRATION: • Changed from github.com/anthonyrawlins/bzzz to chorus.services/bzzz • Updated all import statements across 115+ files • Maintains compatibility while removing personal GitHub account dependency TYPE SYSTEM IMPROVEMENTS: • Resolved duplicate type declarations in crypto package • Added missing type definitions (RoleStatus, TimeRestrictions, KeyStatus, KeyRotationResult) • Proper interface segregation to prevent future cycles ARCHITECTURAL BENEFITS: • Build now progresses past structural issues to normal dependency resolution • Cleaner separation of concerns between packages • Eliminates circular dependencies that prevented compilation • Establishes foundation for scalable codebase growth 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
791 lines
27 KiB
Go
791 lines
27 KiB
Go
// Package slurp provides contextual intelligence capabilities for BZZZ.
|
|
//
|
|
// SLURP (Storage, Logic, Understanding, Retrieval, Processing) implements:
|
|
// - Hierarchical context resolution with bounded depth traversal
|
|
// - Decision-hop temporal analysis for tracking conceptual evolution
|
|
// - Distributed storage with role-based encryption
|
|
// - Context generation restricted to elected admin nodes
|
|
// - Real-time context evolution tracking and validation
|
|
//
|
|
// Architecture:
|
|
// - context/ Hierarchical context resolution and caching
|
|
// - temporal/ Decision-based temporal evolution tracking
|
|
// - storage/ Distributed encrypted storage layer
|
|
// - intelligence/ Context generation and analysis (admin-only)
|
|
// - retrieval/ Context search and query interfaces
|
|
//
|
|
// Integration Points:
|
|
// - pkg/dht Distributed hash table for context storage
|
|
// - pkg/crypto Role-based encryption for access control
|
|
// - pkg/election Admin-only operations coordination
|
|
// - pkg/config Configuration extension for SLURP settings
|
|
//
|
|
// This package follows established BZZZ patterns for interfaces, error handling,
|
|
// and distributed operations while providing native Go implementations of the
|
|
// contextual intelligence capabilities originally prototyped in Python.
|
|
package slurp
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
"time"
|
|
|
|
"chorus.services/bzzz/pkg/config"
|
|
"chorus.services/bzzz/pkg/crypto"
|
|
"chorus.services/bzzz/pkg/dht"
|
|
"chorus.services/bzzz/pkg/election"
|
|
)
|
|
|
|
// SLURP is the main coordinator for contextual intelligence operations.
|
|
//
|
|
// It orchestrates the interaction between context resolution, temporal analysis,
|
|
// distributed storage, and intelligence generation while enforcing security
|
|
// and access controls through integration with existing BZZZ systems.
|
|
//
|
|
// Thread Safety: SLURP is safe for concurrent use across multiple goroutines.
|
|
// All public methods handle synchronization internally.
|
|
type SLURP struct {
|
|
// Configuration and dependencies
|
|
config *config.Config
|
|
dht dht.DHT
|
|
crypto *crypto.AgeCrypto
|
|
election *election.ElectionManager
|
|
|
|
// Core components
|
|
contextResolver ContextResolver
|
|
temporalGraph TemporalGraph
|
|
storage DistributedStorage
|
|
intelligence ContextGenerator
|
|
retrieval QueryEngine
|
|
|
|
// State management
|
|
mu sync.RWMutex
|
|
initialized bool
|
|
adminMode bool
|
|
currentAdmin string
|
|
|
|
// Background processing
|
|
ctx context.Context
|
|
cancel context.CancelFunc
|
|
backgroundTasks sync.WaitGroup
|
|
|
|
// Performance monitoring
|
|
metrics *SLURPMetrics
|
|
|
|
// Event handling
|
|
eventHandlers map[EventType][]EventHandler
|
|
eventMux sync.RWMutex
|
|
}
|
|
|
|
// SLURPConfig holds SLURP-specific configuration that extends the main BZZZ config
|
|
type SLURPConfig struct {
|
|
// Enable/disable SLURP system
|
|
Enabled bool `yaml:"enabled" json:"enabled"`
|
|
|
|
// Context resolution settings
|
|
ContextResolution ContextResolutionConfig `yaml:"context_resolution" json:"context_resolution"`
|
|
|
|
// Temporal analysis settings
|
|
TemporalAnalysis TemporalAnalysisConfig `yaml:"temporal_analysis" json:"temporal_analysis"`
|
|
|
|
// Storage configuration
|
|
Storage SLURPStorageConfig `yaml:"storage" json:"storage"`
|
|
|
|
// Intelligence/generation settings
|
|
Intelligence IntelligenceConfig `yaml:"intelligence" json:"intelligence"`
|
|
|
|
// Performance tuning
|
|
Performance PerformanceConfig `yaml:"performance" json:"performance"`
|
|
|
|
// Security settings
|
|
Security SLURPSecurityConfig `yaml:"security" json:"security"`
|
|
}
|
|
|
|
// ContextResolutionConfig configures hierarchical context resolution
|
|
type ContextResolutionConfig struct {
|
|
// Bounded traversal settings
|
|
MaxHierarchyDepth int `yaml:"max_hierarchy_depth" json:"max_hierarchy_depth"`
|
|
DefaultDepthLimit int `yaml:"default_depth_limit" json:"default_depth_limit"`
|
|
|
|
// Caching configuration
|
|
CacheTTL time.Duration `yaml:"cache_ttl" json:"cache_ttl"`
|
|
CacheMaxSize int64 `yaml:"cache_max_size" json:"cache_max_size"`
|
|
CacheMaxEntries int `yaml:"cache_max_entries" json:"cache_max_entries"`
|
|
|
|
// Resolution behavior
|
|
RequireStrictMatching bool `yaml:"require_strict_matching" json:"require_strict_matching"`
|
|
AllowPartialResolution bool `yaml:"allow_partial_resolution" json:"allow_partial_resolution"`
|
|
MinConfidenceThreshold float64 `yaml:"min_confidence_threshold" json:"min_confidence_threshold"`
|
|
|
|
// Global context settings
|
|
EnableGlobalContexts bool `yaml:"enable_global_contexts" json:"enable_global_contexts"`
|
|
GlobalContextTTL time.Duration `yaml:"global_context_ttl" json:"global_context_ttl"`
|
|
}
|
|
|
|
// TemporalAnalysisConfig configures decision-based temporal evolution tracking
|
|
type TemporalAnalysisConfig struct {
|
|
// Decision hop analysis
|
|
MaxDecisionHops int `yaml:"max_decision_hops" json:"max_decision_hops"`
|
|
DefaultHopLimit int `yaml:"default_hop_limit" json:"default_hop_limit"`
|
|
|
|
// Temporal navigation
|
|
EnableNavigation bool `yaml:"enable_navigation" json:"enable_navigation"`
|
|
MaxNavigationHistory int `yaml:"max_navigation_history" json:"max_navigation_history"`
|
|
|
|
// Staleness detection
|
|
StalenessThreshold float64 `yaml:"staleness_threshold" json:"staleness_threshold"`
|
|
StalenessCheckInterval time.Duration `yaml:"staleness_check_interval" json:"staleness_check_interval"`
|
|
|
|
// Decision analysis
|
|
MinDecisionConfidence float64 `yaml:"min_decision_confidence" json:"min_decision_confidence"`
|
|
MaxDecisionAge time.Duration `yaml:"max_decision_age" json:"max_decision_age"`
|
|
|
|
// Influence propagation
|
|
EnableInfluencePropagation bool `yaml:"enable_influence_propagation" json:"enable_influence_propagation"`
|
|
MaxInfluenceDepth int `yaml:"max_influence_depth" json:"max_influence_depth"`
|
|
}
|
|
|
|
// SLURPStorageConfig configures distributed storage behavior
|
|
type SLURPStorageConfig struct {
|
|
// Storage backend
|
|
Backend string `yaml:"backend" json:"backend"` // "dht", "hybrid"
|
|
|
|
// Encryption settings
|
|
DefaultEncryption bool `yaml:"default_encryption" json:"default_encryption"`
|
|
EncryptionRoles []string `yaml:"encryption_roles" json:"encryption_roles"`
|
|
|
|
// Persistence
|
|
LocalCacheEnabled bool `yaml:"local_cache_enabled" json:"local_cache_enabled"`
|
|
LocalCachePath string `yaml:"local_cache_path" json:"local_cache_path"`
|
|
LocalCacheMaxSize int64 `yaml:"local_cache_max_size" json:"local_cache_max_size"`
|
|
|
|
// Synchronization
|
|
SyncInterval time.Duration `yaml:"sync_interval" json:"sync_interval"`
|
|
SyncTimeout time.Duration `yaml:"sync_timeout" json:"sync_timeout"`
|
|
ConflictResolution string `yaml:"conflict_resolution" json:"conflict_resolution"`
|
|
|
|
// Replication
|
|
ReplicationFactor int `yaml:"replication_factor" json:"replication_factor"`
|
|
ConsistencyLevel string `yaml:"consistency_level" json:"consistency_level"`
|
|
}
|
|
|
|
// IntelligenceConfig configures context generation and analysis
|
|
type IntelligenceConfig struct {
|
|
// Generation settings (admin-only)
|
|
EnableGeneration bool `yaml:"enable_generation" json:"enable_generation"`
|
|
GenerationTimeout time.Duration `yaml:"generation_timeout" json:"generation_timeout"`
|
|
GenerationConcurrency int `yaml:"generation_concurrency" json:"generation_concurrency"`
|
|
|
|
// Analysis settings
|
|
EnableAnalysis bool `yaml:"enable_analysis" json:"enable_analysis"`
|
|
AnalysisInterval time.Duration `yaml:"analysis_interval" json:"analysis_interval"`
|
|
|
|
// Pattern detection
|
|
EnablePatternDetection bool `yaml:"enable_pattern_detection" json:"enable_pattern_detection"`
|
|
PatternMatchThreshold float64 `yaml:"pattern_match_threshold" json:"pattern_match_threshold"`
|
|
|
|
// Quality metrics
|
|
QualityThreshold float64 `yaml:"quality_threshold" json:"quality_threshold"`
|
|
EnableQualityMetrics bool `yaml:"enable_quality_metrics" json:"enable_quality_metrics"`
|
|
|
|
// External integrations
|
|
RAGEndpoint string `yaml:"rag_endpoint" json:"rag_endpoint"`
|
|
RAGTimeout time.Duration `yaml:"rag_timeout" json:"rag_timeout"`
|
|
}
|
|
|
|
// PerformanceConfig configures performance optimization settings
|
|
type PerformanceConfig struct {
|
|
// Concurrency limits
|
|
MaxConcurrentResolutions int `yaml:"max_concurrent_resolutions" json:"max_concurrent_resolutions"`
|
|
MaxConcurrentGenerations int `yaml:"max_concurrent_generations" json:"max_concurrent_generations"`
|
|
MaxConcurrentQueries int `yaml:"max_concurrent_queries" json:"max_concurrent_queries"`
|
|
|
|
// Timeout settings
|
|
DefaultRequestTimeout time.Duration `yaml:"default_request_timeout" json:"default_request_timeout"`
|
|
BackgroundTaskTimeout time.Duration `yaml:"background_task_timeout" json:"background_task_timeout"`
|
|
HealthCheckTimeout time.Duration `yaml:"health_check_timeout" json:"health_check_timeout"`
|
|
|
|
// Resource limits
|
|
MaxMemoryUsage int64 `yaml:"max_memory_usage" json:"max_memory_usage"`
|
|
MaxDiskUsage int64 `yaml:"max_disk_usage" json:"max_disk_usage"`
|
|
|
|
// Batch processing
|
|
DefaultBatchSize int `yaml:"default_batch_size" json:"default_batch_size"`
|
|
MaxBatchSize int `yaml:"max_batch_size" json:"max_batch_size"`
|
|
BatchTimeout time.Duration `yaml:"batch_timeout" json:"batch_timeout"`
|
|
|
|
// Monitoring
|
|
EnableMetrics bool `yaml:"enable_metrics" json:"enable_metrics"`
|
|
MetricsCollectionInterval time.Duration `yaml:"metrics_collection_interval" json:"metrics_collection_interval"`
|
|
}
|
|
|
|
// SLURPSecurityConfig configures security-specific settings
|
|
type SLURPSecurityConfig struct {
|
|
// Access control
|
|
EnforceRoleBasedAccess bool `yaml:"enforce_role_based_access" json:"enforce_role_based_access"`
|
|
DefaultAccessRoles []string `yaml:"default_access_roles" json:"default_access_roles"`
|
|
AdminOnlyOperations []string `yaml:"admin_only_operations" json:"admin_only_operations"`
|
|
|
|
// Audit and logging
|
|
EnableAuditLog bool `yaml:"enable_audit_log" json:"enable_audit_log"`
|
|
AuditLogPath string `yaml:"audit_log_path" json:"audit_log_path"`
|
|
LogSensitiveOperations bool `yaml:"log_sensitive_operations" json:"log_sensitive_operations"`
|
|
|
|
// Encryption
|
|
RequireEncryption bool `yaml:"require_encryption" json:"require_encryption"`
|
|
EncryptionAlgorithm string `yaml:"encryption_algorithm" json:"encryption_algorithm"`
|
|
KeyRotationInterval time.Duration `yaml:"key_rotation_interval" json:"key_rotation_interval"`
|
|
|
|
// Rate limiting
|
|
EnableRateLimiting bool `yaml:"enable_rate_limiting" json:"enable_rate_limiting"`
|
|
DefaultRateLimit int `yaml:"default_rate_limit" json:"default_rate_limit"`
|
|
BurstLimit int `yaml:"burst_limit" json:"burst_limit"`
|
|
}
|
|
|
|
// SLURPMetrics holds performance and operational metrics
|
|
type SLURPMetrics struct {
|
|
// Resolution metrics
|
|
TotalResolutions int64 `json:"total_resolutions"`
|
|
SuccessfulResolutions int64 `json:"successful_resolutions"`
|
|
FailedResolutions int64 `json:"failed_resolutions"`
|
|
AverageResolutionTime time.Duration `json:"average_resolution_time"`
|
|
CacheHitRate float64 `json:"cache_hit_rate"`
|
|
|
|
// Temporal metrics
|
|
TemporalNodes int64 `json:"temporal_nodes"`
|
|
DecisionPaths int64 `json:"decision_paths"`
|
|
InfluenceRelationships int64 `json:"influence_relationships"`
|
|
StaleContexts int64 `json:"stale_contexts"`
|
|
|
|
// Storage metrics
|
|
StoredContexts int64 `json:"stored_contexts"`
|
|
EncryptedContexts int64 `json:"encrypted_contexts"`
|
|
StorageUtilization float64 `json:"storage_utilization"`
|
|
SyncOperations int64 `json:"sync_operations"`
|
|
|
|
// Intelligence metrics
|
|
GenerationRequests int64 `json:"generation_requests"`
|
|
SuccessfulGenerations int64 `json:"successful_generations"`
|
|
AnalysisOperations int64 `json:"analysis_operations"`
|
|
PatternMatches int64 `json:"pattern_matches"`
|
|
|
|
// Performance metrics
|
|
ActiveConnections int64 `json:"active_connections"`
|
|
MemoryUsage int64 `json:"memory_usage"`
|
|
DiskUsage int64 `json:"disk_usage"`
|
|
|
|
// Error metrics
|
|
AuthenticationErrors int64 `json:"authentication_errors"`
|
|
AuthorizationErrors int64 `json:"authorization_errors"`
|
|
TimeoutErrors int64 `json:"timeout_errors"`
|
|
|
|
// Timestamp
|
|
LastUpdated time.Time `json:"last_updated"`
|
|
}
|
|
|
|
// EventType represents different types of SLURP events
|
|
type EventType string
|
|
|
|
const (
|
|
EventContextResolved EventType = "context_resolved"
|
|
EventContextGenerated EventType = "context_generated"
|
|
EventContextEvolved EventType = "context_evolved"
|
|
EventDecisionRecorded EventType = "decision_recorded"
|
|
EventInfluenceAdded EventType = "influence_added"
|
|
EventAdminChanged EventType = "admin_changed"
|
|
EventStalenessDetected EventType = "staleness_detected"
|
|
EventCacheInvalidated EventType = "cache_invalidated"
|
|
EventStorageSynced EventType = "storage_synced"
|
|
EventPatternDetected EventType = "pattern_detected"
|
|
EventErrorOccurred EventType = "error_occurred"
|
|
)
|
|
|
|
// EventHandler defines the interface for handling SLURP events
|
|
type EventHandler func(ctx context.Context, event *SLURPEvent) error
|
|
|
|
// SLURPEvent represents an event within the SLURP system
|
|
type SLURPEvent struct {
|
|
Type EventType `json:"type"`
|
|
Timestamp time.Time `json:"timestamp"`
|
|
Source string `json:"source"`
|
|
Data map[string]interface{} `json:"data"`
|
|
Context map[string]string `json:"context,omitempty"`
|
|
}
|
|
|
|
// NewSLURP creates a new SLURP instance with the provided dependencies.
|
|
//
|
|
// The SLURP system requires integration with existing BZZZ components:
|
|
// - config: Main BZZZ configuration including SLURP settings
|
|
// - dhtInstance: Distributed hash table for storage and discovery
|
|
// - cryptoInstance: Role-based encryption for access control
|
|
// - electionManager: Admin election coordination for restricted operations
|
|
//
|
|
// Returns an initialized but not yet started SLURP instance.
|
|
func NewSLURP(
|
|
config *config.Config,
|
|
dhtInstance dht.DHT,
|
|
cryptoInstance *crypto.AgeCrypto,
|
|
electionManager *election.ElectionManager,
|
|
) (*SLURP, error) {
|
|
if config == nil {
|
|
return nil, fmt.Errorf("config is required")
|
|
}
|
|
if dhtInstance == nil {
|
|
return nil, fmt.Errorf("DHT instance is required")
|
|
}
|
|
if cryptoInstance == nil {
|
|
return nil, fmt.Errorf("crypto instance is required")
|
|
}
|
|
if electionManager == nil {
|
|
return nil, fmt.Errorf("election manager is required")
|
|
}
|
|
|
|
// Validate SLURP configuration
|
|
if err := validateSLURPConfig(&config.Slurp); err != nil {
|
|
return nil, fmt.Errorf("invalid SLURP configuration: %w", err)
|
|
}
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
slurp := &SLURP{
|
|
config: config,
|
|
dht: dhtInstance,
|
|
crypto: cryptoInstance,
|
|
election: electionManager,
|
|
ctx: ctx,
|
|
cancel: cancel,
|
|
metrics: &SLURPMetrics{LastUpdated: time.Now()},
|
|
eventHandlers: make(map[EventType][]EventHandler),
|
|
}
|
|
|
|
return slurp, nil
|
|
}
|
|
|
|
// Initialize initializes all SLURP components and prepares for operation.
|
|
//
|
|
// This method must be called before using any SLURP functionality.
|
|
// It sets up the context resolver, temporal graph, storage layer,
|
|
// intelligence system, and retrieval engine.
|
|
//
|
|
// The initialization process includes:
|
|
// - Loading existing context hierarchies from storage
|
|
// - Setting up encryption keys and access controls
|
|
// - Initializing caches and performance optimizations
|
|
// - Starting background maintenance tasks
|
|
//
|
|
// Returns an error if initialization fails.
|
|
func (s *SLURP) Initialize(ctx context.Context) error {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
if s.initialized {
|
|
return fmt.Errorf("SLURP already initialized")
|
|
}
|
|
|
|
// Check if SLURP is enabled
|
|
if !s.config.Slurp.Enabled {
|
|
return fmt.Errorf("SLURP is disabled in configuration")
|
|
}
|
|
|
|
// TODO: Initialize components in dependency order
|
|
// 1. Initialize storage layer first
|
|
// 2. Initialize context resolver with storage
|
|
// 3. Initialize temporal graph with storage
|
|
// 4. Initialize intelligence with resolver and temporal
|
|
// 5. Initialize retrieval with all components
|
|
// 6. Set up event handlers and background tasks
|
|
|
|
// Set admin status based on current election state
|
|
s.updateAdminStatus()
|
|
|
|
// Set up election event handlers
|
|
if err := s.setupElectionHandlers(); err != nil {
|
|
return fmt.Errorf("failed to setup election handlers: %w", err)
|
|
}
|
|
|
|
// Start background tasks
|
|
s.startBackgroundTasks()
|
|
|
|
s.initialized = true
|
|
|
|
// Emit initialization event
|
|
s.emitEvent(EventContextResolved, map[string]interface{}{
|
|
"action": "system_initialized",
|
|
"admin_mode": s.adminMode,
|
|
"current_admin": s.currentAdmin,
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
// Resolve resolves context for a UCXL address using hierarchical inheritance.
|
|
//
|
|
// This is the primary method for context resolution, implementing bounded
|
|
// hierarchy traversal with caching and role-based access control.
|
|
//
|
|
// Parameters:
|
|
// ctx: Request context for cancellation and timeouts
|
|
// ucxlAddress: The UCXL address to resolve context for
|
|
//
|
|
// Returns:
|
|
// *ResolvedContext: Complete resolved context with metadata
|
|
// error: Any error during resolution
|
|
//
|
|
// The resolution process:
|
|
// 1. Validates the UCXL address format
|
|
// 2. Checks cache for existing resolution
|
|
// 3. Performs bounded hierarchy traversal
|
|
// 4. Applies global contexts if enabled
|
|
// 5. Encrypts result based on current role permissions
|
|
// 6. Caches the result for future requests
|
|
func (s *SLURP) Resolve(ctx context.Context, ucxlAddress string) (*ResolvedContext, error) {
|
|
if !s.initialized {
|
|
return nil, fmt.Errorf("SLURP not initialized")
|
|
}
|
|
|
|
// TODO: Implement context resolution
|
|
// This would delegate to the contextResolver component
|
|
|
|
return nil, fmt.Errorf("not implemented")
|
|
}
|
|
|
|
// ResolveWithDepth resolves context with a specific depth limit.
|
|
//
|
|
// This method provides fine-grained control over the hierarchy traversal
|
|
// depth, allowing callers to optimize performance for specific use cases.
|
|
func (s *SLURP) ResolveWithDepth(ctx context.Context, ucxlAddress string, maxDepth int) (*ResolvedContext, error) {
|
|
if !s.initialized {
|
|
return nil, fmt.Errorf("SLURP not initialized")
|
|
}
|
|
|
|
if maxDepth < 0 {
|
|
return nil, fmt.Errorf("maxDepth cannot be negative")
|
|
}
|
|
|
|
// TODO: Implement depth-limited resolution
|
|
|
|
return nil, fmt.Errorf("not implemented")
|
|
}
|
|
|
|
// BatchResolve efficiently resolves multiple UCXL addresses in parallel.
|
|
//
|
|
// This method is optimized for bulk resolution operations with request
|
|
// deduplication, shared caching, and controlled concurrency.
|
|
func (s *SLURP) BatchResolve(ctx context.Context, addresses []string) (map[string]*ResolvedContext, error) {
|
|
if !s.initialized {
|
|
return nil, fmt.Errorf("SLURP not initialized")
|
|
}
|
|
|
|
if len(addresses) == 0 {
|
|
return make(map[string]*ResolvedContext), nil
|
|
}
|
|
|
|
// TODO: Implement batch resolution with concurrency control
|
|
|
|
return nil, fmt.Errorf("not implemented")
|
|
}
|
|
|
|
// GetTemporalEvolution retrieves the temporal evolution history for a context.
|
|
//
|
|
// This method provides access to decision-based evolution tracking,
|
|
// showing how context has changed through different decision points.
|
|
func (s *SLURP) GetTemporalEvolution(ctx context.Context, ucxlAddress string) ([]*TemporalNode, error) {
|
|
if !s.initialized {
|
|
return nil, fmt.Errorf("SLURP not initialized")
|
|
}
|
|
|
|
// TODO: Delegate to temporal graph component
|
|
|
|
return nil, fmt.Errorf("not implemented")
|
|
}
|
|
|
|
// NavigateDecisionHops navigates through the decision graph by hop distance.
|
|
//
|
|
// This method implements decision-hop based navigation rather than
|
|
// chronological time-based navigation, allowing exploration of
|
|
// conceptually related changes.
|
|
func (s *SLURP) NavigateDecisionHops(ctx context.Context, ucxlAddress string, hops int, direction NavigationDirection) (*TemporalNode, error) {
|
|
if !s.initialized {
|
|
return nil, fmt.Errorf("SLURP not initialized")
|
|
}
|
|
|
|
// TODO: Implement decision-hop navigation
|
|
|
|
return nil, fmt.Errorf("not implemented")
|
|
}
|
|
|
|
// GenerateContext generates new context for a path (admin-only operation).
|
|
//
|
|
// This method is restricted to admin nodes and provides intelligent
|
|
// context generation using analysis of file content, structure, and
|
|
// existing patterns.
|
|
func (s *SLURP) GenerateContext(ctx context.Context, path string, options *GenerationOptions) (*ContextNode, error) {
|
|
if !s.initialized {
|
|
return nil, fmt.Errorf("SLURP not initialized")
|
|
}
|
|
|
|
// Enforce admin-only restriction
|
|
if !s.IsCurrentNodeAdmin() {
|
|
return nil, fmt.Errorf("context generation requires admin privileges")
|
|
}
|
|
|
|
// TODO: Delegate to intelligence component
|
|
|
|
return nil, fmt.Errorf("not implemented")
|
|
}
|
|
|
|
// IsCurrentNodeAdmin returns true if the current node is the elected admin.
|
|
//
|
|
// This method is used throughout SLURP to enforce admin-only operations
|
|
// such as context generation and hierarchy management.
|
|
func (s *SLURP) IsCurrentNodeAdmin() bool {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
return s.adminMode
|
|
}
|
|
|
|
// GetMetrics returns current SLURP performance and operational metrics.
|
|
func (s *SLURP) GetMetrics() *SLURPMetrics {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
|
|
// Return a copy to prevent modification
|
|
metricsCopy := *s.metrics
|
|
metricsCopy.LastUpdated = time.Now()
|
|
return &metricsCopy
|
|
}
|
|
|
|
// RegisterEventHandler registers an event handler for specific event types.
|
|
//
|
|
// Event handlers are called asynchronously when events occur and can be
|
|
// used for monitoring, logging, and reactive operations.
|
|
func (s *SLURP) RegisterEventHandler(eventType EventType, handler EventHandler) {
|
|
s.eventMux.Lock()
|
|
defer s.eventMux.Unlock()
|
|
|
|
if _, exists := s.eventHandlers[eventType]; !exists {
|
|
s.eventHandlers[eventType] = make([]EventHandler, 0)
|
|
}
|
|
|
|
s.eventHandlers[eventType] = append(s.eventHandlers[eventType], handler)
|
|
}
|
|
|
|
// Close gracefully shuts down the SLURP system.
|
|
//
|
|
// This method stops all background tasks, flushes caches, and releases
|
|
// resources. It should be called when the BZZZ node is shutting down.
|
|
func (s *SLURP) Close() error {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
if !s.initialized {
|
|
return nil
|
|
}
|
|
|
|
// Cancel context to stop background tasks
|
|
s.cancel()
|
|
|
|
// Wait for background tasks to complete
|
|
s.backgroundTasks.Wait()
|
|
|
|
// TODO: Close all components in reverse dependency order
|
|
// 1. Stop retrieval engine
|
|
// 2. Stop intelligence system
|
|
// 3. Flush and close temporal graph
|
|
// 4. Flush and close context resolver
|
|
// 5. Close storage layer
|
|
|
|
s.initialized = false
|
|
|
|
return nil
|
|
}
|
|
|
|
// Internal methods
|
|
|
|
func (s *SLURP) updateAdminStatus() {
|
|
if s.election != nil {
|
|
s.adminMode = s.election.IsCurrentAdmin()
|
|
s.currentAdmin = s.election.GetCurrentAdmin()
|
|
}
|
|
}
|
|
|
|
func (s *SLURP) setupElectionHandlers() error {
|
|
if s.election == nil {
|
|
return nil
|
|
}
|
|
|
|
// Set up callbacks for admin changes
|
|
s.election.SetCallbacks(
|
|
s.handleAdminChanged,
|
|
s.handleElectionComplete,
|
|
)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *SLURP) handleAdminChanged(oldAdmin, newAdmin string) {
|
|
s.mu.Lock()
|
|
s.currentAdmin = newAdmin
|
|
s.adminMode = (newAdmin == s.config.Agent.ID)
|
|
s.mu.Unlock()
|
|
|
|
// Emit admin change event
|
|
s.emitEvent(EventAdminChanged, map[string]interface{}{
|
|
"old_admin": oldAdmin,
|
|
"new_admin": newAdmin,
|
|
"is_current_node": s.adminMode,
|
|
})
|
|
}
|
|
|
|
func (s *SLURP) handleElectionComplete(winner string) {
|
|
// Election completion handling if needed
|
|
}
|
|
|
|
func (s *SLURP) startBackgroundTasks() {
|
|
// Start metrics collection
|
|
s.backgroundTasks.Add(1)
|
|
go s.metricsCollectionLoop()
|
|
|
|
// Start cache maintenance
|
|
s.backgroundTasks.Add(1)
|
|
go s.cacheMaintenance()
|
|
|
|
// Start staleness detection
|
|
if s.config.Slurp.TemporalAnalysis.StalenessCheckInterval > 0 {
|
|
s.backgroundTasks.Add(1)
|
|
go s.stalenessDetectionLoop()
|
|
}
|
|
}
|
|
|
|
func (s *SLURP) metricsCollectionLoop() {
|
|
defer s.backgroundTasks.Done()
|
|
|
|
ticker := time.NewTicker(s.config.Slurp.Performance.MetricsCollectionInterval)
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-s.ctx.Done():
|
|
return
|
|
case <-ticker.C:
|
|
s.updateMetrics()
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *SLURP) cacheMaintenance() {
|
|
defer s.backgroundTasks.Done()
|
|
|
|
// TODO: Implement cache maintenance loop
|
|
ticker := time.NewTicker(5 * time.Minute)
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-s.ctx.Done():
|
|
return
|
|
case <-ticker.C:
|
|
// Perform cache cleanup, expire old entries, etc.
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *SLURP) stalenessDetectionLoop() {
|
|
defer s.backgroundTasks.Done()
|
|
|
|
ticker := time.NewTicker(s.config.Slurp.TemporalAnalysis.StalenessCheckInterval)
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-s.ctx.Done():
|
|
return
|
|
case <-ticker.C:
|
|
s.detectStaleContexts()
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *SLURP) updateMetrics() {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
// TODO: Collect metrics from all components
|
|
s.metrics.LastUpdated = time.Now()
|
|
}
|
|
|
|
func (s *SLURP) detectStaleContexts() {
|
|
// TODO: Implement staleness detection
|
|
// This would scan temporal nodes for contexts that haven't been
|
|
// updated recently and may be outdated due to related changes
|
|
}
|
|
|
|
func (s *SLURP) emitEvent(eventType EventType, data map[string]interface{}) {
|
|
event := &SLURPEvent{
|
|
Type: eventType,
|
|
Timestamp: time.Now(),
|
|
Source: "slurp_core",
|
|
Data: data,
|
|
}
|
|
|
|
// Call event handlers asynchronously
|
|
go s.handleEvent(event)
|
|
}
|
|
|
|
func (s *SLURP) handleEvent(event *SLURPEvent) {
|
|
s.eventMux.RLock()
|
|
handlers, exists := s.eventHandlers[event.Type]
|
|
if !exists {
|
|
s.eventMux.RUnlock()
|
|
return
|
|
}
|
|
|
|
// Make a copy of handlers to avoid holding lock during execution
|
|
handlersCopy := make([]EventHandler, len(handlers))
|
|
copy(handlersCopy, handlers)
|
|
s.eventMux.RUnlock()
|
|
|
|
// Execute handlers
|
|
for _, handler := range handlersCopy {
|
|
func(h EventHandler) {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
// Log handler panic but don't crash the system
|
|
}
|
|
}()
|
|
|
|
ctx, cancel := context.WithTimeout(s.ctx, 30*time.Second)
|
|
defer cancel()
|
|
|
|
if err := h(ctx, event); err != nil {
|
|
// Log handler error but continue with other handlers
|
|
}
|
|
}(handler)
|
|
}
|
|
}
|
|
|
|
// validateSLURPConfig validates SLURP configuration for consistency and correctness
|
|
func validateSLURPConfig(config *SLURPConfig) error {
|
|
if config.ContextResolution.MaxHierarchyDepth < 1 {
|
|
return fmt.Errorf("max_hierarchy_depth must be at least 1")
|
|
}
|
|
|
|
if config.ContextResolution.MinConfidenceThreshold < 0 || config.ContextResolution.MinConfidenceThreshold > 1 {
|
|
return fmt.Errorf("min_confidence_threshold must be between 0 and 1")
|
|
}
|
|
|
|
if config.TemporalAnalysis.MaxDecisionHops < 1 {
|
|
return fmt.Errorf("max_decision_hops must be at least 1")
|
|
}
|
|
|
|
if config.TemporalAnalysis.StalenessThreshold < 0 || config.TemporalAnalysis.StalenessThreshold > 1 {
|
|
return fmt.Errorf("staleness_threshold must be between 0 and 1")
|
|
}
|
|
|
|
if config.Performance.MaxConcurrentResolutions < 1 {
|
|
return fmt.Errorf("max_concurrent_resolutions must be at least 1")
|
|
}
|
|
|
|
return nil
|
|
} |