package ucxi import ( "context" "encoding/json" "fmt" "io" "log" "net/http" "strings" "sync" "time" "chorus.services/bzzz/pkg/ucxl" ) // Server represents a UCXI HTTP server for UCXL operations type Server struct { // HTTP server configuration server *http.Server port int basePath string // Address resolution resolver AddressResolver // Content storage storage ContentStorage // Temporal navigation navigators map[string]*ucxl.TemporalNavigator navMutex sync.RWMutex // Server state running bool ctx context.Context cancel context.CancelFunc // Middleware and logging logger Logger // Response building responseBuilder *ucxl.ResponseBuilder } // AddressResolver interface for resolving UCXL addresses to actual content type AddressResolver interface { Resolve(ctx context.Context, addr *ucxl.Address) (*ResolvedContent, error) Announce(ctx context.Context, addr *ucxl.Address, content *Content) error Discover(ctx context.Context, pattern *ucxl.Address) ([]*ResolvedContent, error) } // ContentStorage interface for storing and retrieving content type ContentStorage interface { Store(ctx context.Context, key string, content *Content) error Retrieve(ctx context.Context, key string) (*Content, error) Delete(ctx context.Context, key string) error List(ctx context.Context, prefix string) ([]string, error) } // Logger interface for server logging type Logger interface { Info(msg string, fields ...interface{}) Warn(msg string, fields ...interface{}) Error(msg string, fields ...interface{}) Debug(msg string, fields ...interface{}) } // Content represents content stored at a UCXL address type Content struct { Data []byte `json:"data"` ContentType string `json:"content_type"` Metadata map[string]string `json:"metadata"` Version int `json:"version"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` Author string `json:"author,omitempty"` Checksum string `json:"checksum,omitempty"` } // ResolvedContent represents content resolved from a UCXL address type ResolvedContent struct { Address *ucxl.Address `json:"address"` Content *Content `json:"content"` Source string `json:"source"` // Source node/peer ID Resolved time.Time `json:"resolved"` // Resolution timestamp TTL time.Duration `json:"ttl"` // Time to live for caching } // Deprecated: Use ucxl.UCXLResponse and ucxl.UCXLError instead // Legacy Response type kept for backward compatibility type Response struct { Success bool `json:"success"` Data interface{} `json:"data,omitempty"` Error string `json:"error,omitempty"` Timestamp time.Time `json:"timestamp"` RequestID string `json:"request_id,omitempty"` Version string `json:"version"` } // Deprecated: Use ucxl.UCXLError instead // Legacy ErrorResponse type kept for backward compatibility type ErrorResponse struct { Code int `json:"code"` Message string `json:"message"` Details string `json:"details,omitempty"` } // UCXLValidationError represents a structured UCXL validation error type UCXLValidationError struct { Code string `json:"code"` Field string `json:"field"` Message string `json:"message"` Address string `json:"address"` } // ServerConfig holds server configuration type ServerConfig struct { Port int `json:"port"` BasePath string `json:"base_path"` Resolver AddressResolver `json:"-"` Storage ContentStorage `json:"-"` Logger Logger `json:"-"` } // NewServer creates a new UCXI server func NewServer(config ServerConfig) *Server { ctx, cancel := context.WithCancel(context.Background()) s := &Server{ port: config.Port, basePath: strings.TrimSuffix(config.BasePath, "/"), resolver: config.Resolver, storage: config.Storage, logger: config.Logger, navigators: make(map[string]*ucxl.TemporalNavigator), ctx: ctx, cancel: cancel, } // Initialize response builder with server source s.responseBuilder = ucxl.NewResponseBuilder("", "ucxi-server") return s } // Start starts the UCXI HTTP server func (s *Server) Start() error { if s.running { return fmt.Errorf("server is already running") } mux := http.NewServeMux() // Register routes s.registerRoutes(mux) s.server = &http.Server{ Addr: fmt.Sprintf(":%d", s.port), Handler: s.withMiddleware(mux), ReadTimeout: 30 * time.Second, WriteTimeout: 30 * time.Second, IdleTimeout: 60 * time.Second, } s.running = true s.logger.Info("Starting UCXI server", "port", s.port, "base_path", s.basePath) return s.server.ListenAndServe() } // Stop stops the UCXI HTTP server func (s *Server) Stop() error { if !s.running { return nil } s.logger.Info("Stopping UCXI server") s.cancel() s.running = false ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() return s.server.Shutdown(ctx) } // registerRoutes registers all UCXI HTTP routes func (s *Server) registerRoutes(mux *http.ServeMux) { prefix := s.basePath + "/ucxi/v1" // Content operations mux.HandleFunc(prefix+"/get", s.handleGet) mux.HandleFunc(prefix+"/put", s.handlePut) mux.HandleFunc(prefix+"/post", s.handlePost) mux.HandleFunc(prefix+"/delete", s.handleDelete) // Discovery and announcement mux.HandleFunc(prefix+"/announce", s.handleAnnounce) mux.HandleFunc(prefix+"/discover", s.handleDiscover) // Temporal navigation mux.HandleFunc(prefix+"/navigate", s.handleNavigate) // Server status and health mux.HandleFunc(prefix+"/health", s.handleHealth) mux.HandleFunc(prefix+"/status", s.handleStatus) // Role-based collaboration endpoints mux.HandleFunc(prefix+"/collaboration", s.handleCollaboration) } // handleGet handles GET requests for retrieving content func (s *Server) handleGet(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { s.writeErrorResponse(w, http.StatusMethodNotAllowed, "Method not allowed", "") return } addressStr := r.URL.Query().Get("address") if addressStr == "" { s.writeErrorResponse(w, http.StatusBadRequest, "Missing address parameter", "") return } addr, err := ucxl.Parse(addressStr) if err != nil { if validationErr, ok := err.(*ucxl.ValidationError); ok { s.writeUCXLValidationError(w, validationErr) } else { s.writeErrorResponse(w, http.StatusBadRequest, "Invalid UCXL address", err.Error()) } return } // Resolve the address resolved, err := s.resolver.Resolve(r.Context(), addr) if err != nil { s.writeErrorResponse(w, http.StatusNotFound, "Failed to resolve address", err.Error()) return } s.writeSuccessResponse(w, resolved) } // handlePut handles PUT requests for storing content func (s *Server) handlePut(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPut { s.writeErrorResponse(w, http.StatusMethodNotAllowed, "Method not allowed", "") return } addressStr := r.URL.Query().Get("address") if addressStr == "" { s.writeErrorResponse(w, http.StatusBadRequest, "Missing address parameter", "") return } addr, err := ucxl.Parse(addressStr) if err != nil { if validationErr, ok := err.(*ucxl.ValidationError); ok { s.writeUCXLValidationError(w, validationErr) } else { s.writeErrorResponse(w, http.StatusBadRequest, "Invalid UCXL address", err.Error()) } return } // Read content from request body body, err := io.ReadAll(r.Body) if err != nil { s.writeErrorResponse(w, http.StatusBadRequest, "Failed to read request body", err.Error()) return } content := &Content{ Data: body, ContentType: r.Header.Get("Content-Type"), Metadata: make(map[string]string), CreatedAt: time.Now(), UpdatedAt: time.Now(), Author: r.Header.Get("X-Author"), } // Copy custom metadata from headers for key, values := range r.Header { if strings.HasPrefix(key, "X-Meta-") { metaKey := strings.TrimPrefix(key, "X-Meta-") if len(values) > 0 { content.Metadata[metaKey] = values[0] } } } // Store the content key := s.generateStorageKey(addr) if err := s.storage.Store(r.Context(), key, content); err != nil { s.writeErrorResponse(w, http.StatusInternalServerError, "Failed to store content", err.Error()) return } // Announce the content if err := s.resolver.Announce(r.Context(), addr, content); err != nil { s.logger.Warn("Failed to announce content", "error", err.Error(), "address", addr.String()) // Don't fail the request if announcement fails } response := map[string]interface{}{ "address": addr.String(), "key": key, "stored": true, } s.writeSuccessResponse(w, response) } // handlePost handles POST requests for updating content func (s *Server) handlePost(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { s.writeErrorResponse(w, http.StatusMethodNotAllowed, "Method not allowed", "") return } // POST is similar to PUT but may have different semantics // For now, delegate to PUT handler s.handlePut(w, r) } // handleDelete handles DELETE requests for removing content func (s *Server) handleDelete(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodDelete { s.writeErrorResponse(w, http.StatusMethodNotAllowed, "Method not allowed", "") return } addressStr := r.URL.Query().Get("address") if addressStr == "" { s.writeErrorResponse(w, http.StatusBadRequest, "Missing address parameter", "") return } addr, err := ucxl.Parse(addressStr) if err != nil { if validationErr, ok := err.(*ucxl.ValidationError); ok { s.writeUCXLValidationError(w, validationErr) } else { s.writeErrorResponse(w, http.StatusBadRequest, "Invalid UCXL address", err.Error()) } return } key := s.generateStorageKey(addr) if err := s.storage.Delete(r.Context(), key); err != nil { s.writeErrorResponse(w, http.StatusInternalServerError, "Failed to delete content", err.Error()) return } response := map[string]interface{}{ "address": addr.String(), "key": key, "deleted": true, } s.writeSuccessResponse(w, response) } // handleAnnounce handles content announcement requests func (s *Server) handleAnnounce(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { s.writeErrorResponse(w, http.StatusMethodNotAllowed, "Method not allowed", "") return } var request struct { Address string `json:"address"` Content Content `json:"content"` } if err := json.NewDecoder(r.Body).Decode(&request); err != nil { s.writeErrorResponse(w, http.StatusBadRequest, "Invalid JSON request", err.Error()) return } addr, err := ucxl.Parse(request.Address) if err != nil { if validationErr, ok := err.(*ucxl.ValidationError); ok { s.writeUCXLValidationError(w, validationErr) } else { s.writeErrorResponse(w, http.StatusBadRequest, "Invalid UCXL address", err.Error()) } return } if err := s.resolver.Announce(r.Context(), addr, &request.Content); err != nil { s.writeErrorResponse(w, http.StatusInternalServerError, "Failed to announce content", err.Error()) return } response := map[string]interface{}{ "address": addr.String(), "announced": true, } s.writeSuccessResponse(w, response) } // handleDiscover handles content discovery requests func (s *Server) handleDiscover(w http.ResponseWriter, r *http.Request) { requestID := s.getRequestID(r) builder := ucxl.NewResponseBuilder(requestID, "ucxi-server") path := r.URL.Path if r.Method != http.MethodGet { err := builder.MethodNotAllowed([]string{"GET"}, path) s.writeUCXLError(w, err) return } pattern := r.URL.Query().Get("pattern") if pattern == "" { err := builder.BadRequest("Missing pattern parameter", path) s.writeUCXLError(w, err) return } addr, err := ucxl.Parse(pattern) if err != nil { ucxlErr := builder.InvalidAddress("Invalid UCXL pattern format", path, map[string]interface{}{ "provided_pattern": pattern, "parse_error": err.Error(), }) s.writeUCXLError(w, ucxlErr) return } results, err := s.resolver.Discover(r.Context(), addr) if err != nil { ucxlErr := builder.ErrorWithDetails(ucxl.CodeInternalError, "Discovery operation failed", path, map[string]interface{}{ "pattern": addr.String(), "discovery_error": err.Error(), }) s.writeUCXLError(w, ucxlErr) return } responseData := map[string]interface{}{ "pattern": addr.String(), "results": results, "results_count": len(results), } response := builder.OK(responseData) s.writeUCXLResponse(w, response) } // handleNavigate handles temporal navigation requests func (s *Server) handleNavigate(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { s.writeErrorResponse(w, http.StatusMethodNotAllowed, "Method not allowed", "") return } var request struct { Address string `json:"address"` TemporalSegment string `json:"temporal_segment"` } if err := json.NewDecoder(r.Body).Decode(&request); err != nil { s.writeErrorResponse(w, http.StatusBadRequest, "Invalid JSON request", err.Error()) return } addr, err := ucxl.Parse(request.Address) if err != nil { if validationErr, ok := err.(*ucxl.ValidationError); ok { s.writeUCXLValidationError(w, validationErr) } else { s.writeErrorResponse(w, http.StatusBadRequest, "Invalid UCXL address", err.Error()) } return } // Get or create navigator for this address context navKey := s.generateNavigatorKey(addr) navigator := s.getOrCreateNavigator(navKey, 10) // Default to 10 versions // Parse the new temporal segment tempAddr := fmt.Sprintf("ucxl://temp:temp@temp:temp/%s", request.TemporalSegment) tempParsed, err := ucxl.Parse(tempAddr) if err != nil { s.writeErrorResponse(w, http.StatusBadRequest, "Invalid temporal segment", err.Error()) return } // Perform navigation result, err := navigator.Navigate(tempParsed.TemporalSegment) if err != nil { s.writeErrorResponse(w, http.StatusBadRequest, "Navigation failed", err.Error()) return } s.writeSuccessResponse(w, result) } // handleHealth handles health check requests func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { s.writeErrorResponse(w, http.StatusMethodNotAllowed, "Method not allowed", "") return } health := map[string]interface{}{ "status": "healthy", "running": s.running, "uptime": time.Now().UTC(), } s.writeSuccessResponse(w, health) } // handleStatus handles server status requests // Implements requirements from Issue 010 - Status Endpoints and Config Surface // Extended to include role-based collaboration and HMMM integration status func (s *Server) handleStatus(w http.ResponseWriter, r *http.Request) { requestID := s.getRequestID(r) builder := ucxl.NewResponseBuilder(requestID, "ucxi-server") path := r.URL.Path if r.Method != http.MethodGet { err := builder.MethodNotAllowed([]string{"GET"}, path) s.writeUCXLError(w, err) return } s.navMutex.RLock() navigatorCount := len(s.navigators) navigatorKeys := make([]string, 0, len(s.navigators)) for key := range s.navigators { navigatorKeys = append(navigatorKeys, key) } s.navMutex.RUnlock() // Get resolver and storage metrics if available resolverStats := s.getResolverStats() storageMetrics := s.getStorageMetrics() collaborationStatus := s.getCollaborationStatus() hmmmIntegrationStatus := s.getHmmmIntegrationStatus() status := map[string]interface{}{ "server": map[string]interface{}{ "port": s.port, "base_path": s.basePath, "running": s.running, "version": "2.1.0", // Incremented for role-based collaboration support "started_at": time.Now().Add(-time.Hour).UTC(), // Placeholder - would track actual start time }, "ucxi": map[string]interface{}{ "enabled": s.running, "endpoints": []string{ "/get", "/put", "/post", "/delete", "/announce", "/discover", "/navigate", "/health", "/status", "/collaboration", }, }, "resolver": resolverStats, "storage": storageMetrics, "navigators": map[string]interface{}{ "active_count": navigatorCount, "keys": navigatorKeys, }, "p2p": map[string]interface{}{ "enabled": s.resolver != nil, "announce_enabled": s.resolver != nil, "discover_enabled": s.resolver != nil, }, "collaboration": collaborationStatus, "hmmm_integration": hmmmIntegrationStatus, "metrics": map[string]interface{}{ "timestamp": time.Now().UTC(), "uptime_seconds": int64(time.Hour.Seconds()), // Placeholder }, } response := builder.OK(status) s.writeUCXLResponse(w, response) } // handleCollaboration handles role-based collaboration endpoint requests func (s *Server) handleCollaboration(w http.ResponseWriter, r *http.Request) { requestID := s.getRequestID(r) builder := ucxl.NewResponseBuilder(requestID, "ucxi-server") path := r.URL.Path switch r.Method { case http.MethodGet: s.handleGetCollaboration(w, r, builder, path) case http.MethodPost: s.handlePostCollaboration(w, r, builder, path) default: err := builder.MethodNotAllowed([]string{"GET", "POST"}, path) s.writeUCXLError(w, err) } } // handleGetCollaboration handles GET requests for collaboration status func (s *Server) handleGetCollaboration(w http.ResponseWriter, r *http.Request, builder *ucxl.ResponseBuilder, path string) { // Get query parameters for filtering roleFilter := r.URL.Query().Get("role") projectFilter := r.URL.Query().Get("project") expertiseFilter := r.URL.Query().Get("expertise") collaborationData := map[string]interface{}{ "system": s.getCollaborationStatus(), "filters_applied": map[string]interface{}{ "role": roleFilter, "project": projectFilter, "expertise": expertiseFilter, }, } // If specific filters are requested, provide more detailed information if roleFilter != "" || projectFilter != "" || expertiseFilter != "" { collaborationData["filtered_results"] = s.getFilteredCollaborationResults(roleFilter, projectFilter, expertiseFilter) } // Add active collaboration sessions (would be populated from actual pubsub system) collaborationData["active_sessions"] = []map[string]interface{}{ { "type": "expertise_request", "from_role": "junior_developer", "required_expertise": []string{"api_design", "error_handling"}, "project_id": "bzzz", "thread_id": "thread-123", "participants": []string{"claude", "alice"}, "status": "active", "created_at": time.Now().Add(-10 * time.Minute).UTC(), }, { "type": "project_update", "from_role": "tech_lead", "project_id": "bzzz", "thread_id": "thread-456", "deliverable": "api_standardization", "status": "in_progress", "progress": 75, "created_at": time.Now().Add(-5 * time.Minute).UTC(), }, } response := builder.OK(collaborationData) s.writeUCXLResponse(w, response) } // handlePostCollaboration handles POST requests for initiating collaboration func (s *Server) handlePostCollaboration(w http.ResponseWriter, r *http.Request, builder *ucxl.ResponseBuilder, path string) { var request struct { Type string `json:"type"` FromRole string `json:"from_role"` ToRoles []string `json:"to_roles,omitempty"` RequiredExpertise []string `json:"required_expertise,omitempty"` ProjectID string `json:"project_id,omitempty"` Priority string `json:"priority,omitempty"` Data map[string]interface{} `json:"data"` } if err := json.NewDecoder(r.Body).Decode(&request); err != nil { ucxlErr := builder.BadRequest("Invalid JSON request body", path) s.writeUCXLError(w, ucxlErr) return } // Validate collaboration request if request.Type == "" { ucxlErr := builder.ErrorWithDetails(ucxl.CodeInvalidPayload, "Missing collaboration type", path, map[string]interface{}{ "field": "type", "valid_types": []string{ "expertise_request", "mentorship_request", "project_update", "status_update", "work_allocation", "deliverable_ready", }, }) s.writeUCXLError(w, ucxlErr) return } if request.FromRole == "" { ucxlErr := builder.ErrorWithDetails(ucxl.CodeInvalidPayload, "Missing from_role", path, map[string]interface{}{ "field": "from_role", "message": "Collaboration requests must specify the initiating role", }) s.writeUCXLError(w, ucxlErr) return } // Generate collaboration session ID threadID := fmt.Sprintf("thread-%s-%d", request.Type, time.Now().Unix()) // In a real implementation, this would trigger pubsub messages // For now, we simulate the response collaborationResult := map[string]interface{}{ "collaboration_initiated": true, "thread_id": threadID, "type": request.Type, "from_role": request.FromRole, "to_roles": request.ToRoles, "required_expertise": request.RequiredExpertise, "project_id": request.ProjectID, "priority": request.Priority, "status": "initiated", "created_at": time.Now().UTC(), } // Add type-specific response data switch request.Type { case "expertise_request": collaborationResult["expected_response_time"] = "15m" collaborationResult["routing"] = "expertise_based" case "mentorship_request": collaborationResult["mentorship_type"] = "code_review" collaborationResult["routing"] = "seniority_based" case "project_update": collaborationResult["broadcast_scope"] = "project_wide" collaborationResult["routing"] = "project_based" } response := builder.Created(collaborationResult) s.writeUCXLResponse(w, response) } // getFilteredCollaborationResults returns filtered collaboration data func (s *Server) getFilteredCollaborationResults(role, project, expertise string) map[string]interface{} { // In a real implementation, this would query the actual pubsub system // For now, return simulated filtered results results := map[string]interface{}{ "matching_agents": []map[string]interface{}{}, "active_topics": []string{}, "recent_activity": []map[string]interface{}{}, } if role != "" { results["matching_agents"] = []map[string]interface{}{ { "agent_id": "claude", "role": role, "expertise": []string{"api_design", "error_handling", "documentation"}, "availability": "available", "last_seen": time.Now().Add(-2 * time.Minute).UTC(), }, } results["active_topics"] = []string{ fmt.Sprintf("bzzz/roles/%s/v1", strings.ToLower(strings.ReplaceAll(role, " ", "_"))), } } if project != "" { results["project_topics"] = []string{ fmt.Sprintf("bzzz/projects/%s/coordination/v1", project), } results["project_status"] = map[string]interface{}{ "project_id": project, "active_collaborations": 2, "recent_deliverables": []string{"api_standardization"}, } } if expertise != "" { results["expertise_topics"] = []string{ fmt.Sprintf("bzzz/expertise/%s/v1", strings.ToLower(strings.ReplaceAll(expertise, " ", "_"))), } } return results } // getResolverStats returns resolver registry statistics func (s *Server) getResolverStats() map[string]interface{} { if s.resolver == nil { return map[string]interface{}{ "enabled": false, "error": "resolver not configured", } } // Basic resolver statistics // In a real implementation, these would come from the resolver interface return map[string]interface{}{ "enabled": true, "operations": map[string]interface{}{ "resolve_count": 0, // Would track actual metrics "announce_count": 0, // Would track actual metrics "discover_count": 0, // Would track actual metrics }, "performance": map[string]interface{}{ "avg_resolve_time_ms": 0, "success_rate": 1.0, }, } } // getStorageMetrics returns storage performance metrics func (s *Server) getStorageMetrics() map[string]interface{} { if s.storage == nil { return map[string]interface{}{ "enabled": false, "error": "storage not configured", } } // Basic storage metrics // In a real implementation, these would come from the storage interface return map[string]interface{}{ "enabled": true, "operations": map[string]interface{}{ "store_count": 0, // Would track actual metrics "retrieve_count": 0, // Would track actual metrics "delete_count": 0, // Would track actual metrics }, "cache": map[string]interface{}{ "size": 0, // Would track cache size "hit_rate": 0.0, // Would track cache hit rate "miss_rate": 0.0, // Would track cache miss rate }, "performance": map[string]interface{}{ "avg_store_time_ms": 0, "avg_retrieve_time_ms": 0, }, } } // getCollaborationStatus returns role-based collaboration system status func (s *Server) getCollaborationStatus() map[string]interface{} { return map[string]interface{}{ "enabled": true, "features": map[string]interface{}{ "role_based_messaging": true, "expertise_routing": true, "mentorship_support": true, "project_coordination": true, "status_updates": true, }, "pubsub": map[string]interface{}{ "topics": map[string]interface{}{ "bzzz_coordination": "bzzz/coordination/v1", "hmmm_meta_discussion": "hmmm/meta-discussion/v1", "context_feedback": "bzzz/context-feedback/v1", }, "dynamic_topics": map[string]interface{}{ "role_based_enabled": true, "project_topics_enabled": true, "expertise_routing_enabled": true, }, }, "message_types": []string{ "role_announcement", "expertise_request", "expertise_response", "status_update", "work_allocation", "role_collaboration", "mentorship_request", "mentorship_response", "project_update", "deliverable_ready", }, "metrics": map[string]interface{}{ "active_roles": 0, // Would track from actual pubsub system "active_projects": 0, // Would track from actual pubsub system "collaboration_events": 0, // Would track collaboration message counts }, } } // getHmmmIntegrationStatus returns HMMM adapter integration status func (s *Server) getHmmmIntegrationStatus() map[string]interface{} { return map[string]interface{}{ "enabled": true, "adapter": map[string]interface{}{ "version": "1.0.0", "raw_publish_enabled": true, "topic_auto_join": true, }, "features": map[string]interface{}{ "slurp_event_integration": true, "per_issue_rooms": true, "consensus_driven_events": true, "context_updates": true, }, "topics": map[string]interface{}{ "slurp_events": "hmmm/slurp-events/v1", "context_updates": "hmmm/context-updates/v1", "issue_discussions": "hmmm/issues/{issue_id}/v1", }, "message_types": []string{ "slurp_event_generated", "slurp_event_ack", "slurp_context_update", "meta_discussion", "coordination_request", "dependency_alert", "escalation_trigger", }, "metrics": map[string]interface{}{ "slurp_events_generated": 0, // Would track actual metrics "slurp_events_acknowledged": 0, // Would track actual metrics "active_discussions": 0, // Would track active HMMM discussions "consensus_sessions": 0, // Would track consensus sessions }, } } // Utility methods // generateStorageKey generates a storage key from a UCXL address func (s *Server) generateStorageKey(addr *ucxl.Address) string { return fmt.Sprintf("%s:%s@%s:%s/%s", addr.Agent, addr.Role, addr.Project, addr.Task, addr.TemporalSegment.String()) } // generateNavigatorKey generates a navigator key from a UCXL address func (s *Server) generateNavigatorKey(addr *ucxl.Address) string { return fmt.Sprintf("%s:%s@%s:%s", addr.Agent, addr.Role, addr.Project, addr.Task) } // getOrCreateNavigator gets or creates a temporal navigator func (s *Server) getOrCreateNavigator(key string, maxVersion int) *ucxl.TemporalNavigator { s.navMutex.Lock() defer s.navMutex.Unlock() if navigator, exists := s.navigators[key]; exists { return navigator } navigator := ucxl.NewTemporalNavigator(maxVersion) s.navigators[key] = navigator return navigator } // withMiddleware wraps the handler with common middleware func (s *Server) withMiddleware(handler http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Add CORS headers w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Author, X-Meta-*") // Handle preflight requests if r.Method == http.MethodOptions { w.WriteHeader(http.StatusOK) return } // Set content type to JSON by default w.Header().Set("Content-Type", "application/json") // Log request start := time.Now() s.logger.Debug("Request", "method", r.Method, "url", r.URL.String(), "remote", r.RemoteAddr) // Call the handler handler.ServeHTTP(w, r) // Log response duration := time.Since(start) s.logger.Debug("Response", "duration", duration.String()) }) } // writeSuccessResponse writes a successful JSON response func (s *Server) writeSuccessResponse(w http.ResponseWriter, data interface{}) { response := Response{ Success: true, Data: data, Timestamp: time.Now().UTC(), Version: "1.0.0", } w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(response) } // writeErrorResponse writes an error JSON response func (s *Server) writeErrorResponse(w http.ResponseWriter, statusCode int, message, details string) { response := Response{ Success: false, Error: message, Timestamp: time.Now().UTC(), Version: "1.0.0", } if details != "" { response.Data = map[string]string{"details": details} } w.WriteHeader(statusCode) json.NewEncoder(w).Encode(response) } // writeUCXLValidationError writes a structured UCXL validation error response func (s *Server) writeUCXLValidationError(w http.ResponseWriter, validationErr *ucxl.ValidationError) { ucxlError := UCXLValidationError{ Code: "UCXL-400-INVALID_ADDRESS", Field: validationErr.Field, Message: validationErr.Message, Address: validationErr.Raw, } response := Response{ Success: false, Error: "Invalid UCXL address", Data: ucxlError, Timestamp: time.Now().UTC(), Version: "1.0.0", } w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(response) } // writeUCXLResponse writes a standardized UCXL success response func (s *Server) writeUCXLResponse(w http.ResponseWriter, response *ucxl.UCXLResponse) { httpStatus := ucxl.GetHTTPStatus(response.Response.Code) w.WriteHeader(httpStatus) json.NewEncoder(w).Encode(response) } // writeUCXLError writes a standardized UCXL error response func (s *Server) writeUCXLError(w http.ResponseWriter, error *ucxl.UCXLError) { httpStatus := ucxl.GetHTTPStatus(error.Error.Code) w.WriteHeader(httpStatus) json.NewEncoder(w).Encode(error) } // getRequestID extracts or generates a request ID func (s *Server) getRequestID(r *http.Request) string { if r != nil { if requestID := r.Header.Get("X-Request-ID"); requestID != "" { return requestID } if requestID := r.Header.Get("Request-ID"); requestID != "" { return requestID } } // Generate a new request ID return time.Now().Format("20060102-150405") + "-" + s.randomString(8) } // randomString generates a random string for request IDs func (s *Server) randomString(length int) string { const charset = "abcdefghijklmnopqrstuvwxyz0123456789" result := make([]byte, length) for i := range result { result[i] = charset[time.Now().UnixNano()%(int64(len(charset)))] } return string(result) } // Simple logger implementation type SimpleLogger struct{} func (l SimpleLogger) Info(msg string, fields ...interface{}) { log.Printf("INFO: %s %v", msg, fields) } func (l SimpleLogger) Warn(msg string, fields ...interface{}) { log.Printf("WARN: %s %v", msg, fields) } func (l SimpleLogger) Error(msg string, fields ...interface{}) { log.Printf("ERROR: %s %v", msg, fields) } func (l SimpleLogger) Debug(msg string, fields ...interface{}) { log.Printf("DEBUG: %s %v", msg, fields) }