Files
bzzz/pkg/ucxl/codes.go
anthonyrawlins 92779523c0 🚀 Complete BZZZ Issue Resolution - All 17 Issues Solved
Comprehensive multi-agent implementation addressing all issues from INDEX.md:

## Core Architecture & Validation
-  Issue 001: UCXL address validation at all system boundaries
-  Issue 002: Fixed search parsing bug in encrypted storage
-  Issue 003: Wired UCXI P2P announce and discover functionality
-  Issue 011: Aligned temporal grammar and documentation
-  Issue 012: SLURP idempotency, backpressure, and DLQ implementation
-  Issue 013: Linked SLURP events to UCXL decisions and DHT

## API Standardization & Configuration
-  Issue 004: Standardized UCXI payloads to UCXL codes
-  Issue 010: Status endpoints and configuration surface

## Infrastructure & Operations
-  Issue 005: Election heartbeat on admin transition
-  Issue 006: Active health checks for PubSub and DHT
-  Issue 007: DHT replication and provider records
-  Issue 014: SLURP leadership lifecycle and health probes
-  Issue 015: Comprehensive monitoring, SLOs, and alerts

## Security & Access Control
-  Issue 008: Key rotation and role-based access policies

## Testing & Quality Assurance
-  Issue 009: Integration tests for UCXI + DHT encryption + search
-  Issue 016: E2E tests for HMMM → SLURP → UCXL workflow

## HMMM Integration
-  Issue 017: HMMM adapter wiring and comprehensive testing

## Key Features Delivered:
- Enterprise-grade security with automated key rotation
- Comprehensive monitoring with Prometheus/Grafana stack
- Role-based collaboration with HMMM integration
- Complete API standardization with UCXL response formats
- Full test coverage with integration and E2E testing
- Production-ready infrastructure monitoring and alerting

All solutions include comprehensive testing, documentation, and
production-ready implementations.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-29 12:39:38 +10:00

333 lines
11 KiB
Go

package ucxl
import (
"time"
)
// UCXLCode represents a standardized UCXL response/error code
type UCXLCode string
// Standard UCXL response codes
const (
// Success codes (2xx range)
CodeSuccess UCXLCode = "UCXL-200-SUCCESS"
CodeCreated UCXLCode = "UCXL-201-CREATED"
CodeAccepted UCXLCode = "UCXL-202-ACCEPTED"
CodeNoContent UCXLCode = "UCXL-204-NO_CONTENT"
// Client error codes (4xx range)
CodeBadRequest UCXLCode = "UCXL-400-BAD_REQUEST"
CodeInvalidAddress UCXLCode = "UCXL-400-INVALID_ADDRESS"
CodeInvalidPayload UCXLCode = "UCXL-400-INVALID_PAYLOAD"
CodeUnauthorized UCXLCode = "UCXL-401-UNAUTHORIZED"
CodeForbidden UCXLCode = "UCXL-403-FORBIDDEN"
CodeNotFound UCXLCode = "UCXL-404-NOT_FOUND"
CodeMethodNotAllowed UCXLCode = "UCXL-405-METHOD_NOT_ALLOWED"
CodeConflict UCXLCode = "UCXL-409-CONFLICT"
CodeUnprocessable UCXLCode = "UCXL-422-UNPROCESSABLE"
CodeTooManyRequests UCXLCode = "UCXL-429-TOO_MANY_REQUESTS"
// Server error codes (5xx range)
CodeInternalError UCXLCode = "UCXL-500-INTERNAL_ERROR"
CodeNotImplemented UCXLCode = "UCXL-501-NOT_IMPLEMENTED"
CodeBadGateway UCXLCode = "UCXL-502-BAD_GATEWAY"
CodeServiceUnavailable UCXLCode = "UCXL-503-SERVICE_UNAVAILABLE"
CodeGatewayTimeout UCXLCode = "UCXL-504-GATEWAY_TIMEOUT"
// UCXI-specific codes
CodeResolutionFailed UCXLCode = "UCXL-404-RESOLUTION_FAILED"
CodeStorageFailed UCXLCode = "UCXL-500-STORAGE_FAILED"
CodeAnnounceFailed UCXLCode = "UCXL-500-ANNOUNCE_FAILED"
CodeNavigationFailed UCXLCode = "UCXL-422-NAVIGATION_FAILED"
CodeTemporalInvalid UCXLCode = "UCXL-400-TEMPORAL_INVALID"
// Role-based collaboration codes
CodeCollaborationFailed UCXLCode = "UCXL-500-COLLABORATION_FAILED"
CodeInvalidRole UCXLCode = "UCXL-400-INVALID_ROLE"
CodeExpertiseNotAvailable UCXLCode = "UCXL-404-EXPERTISE_NOT_AVAILABLE"
CodeMentorshipUnavailable UCXLCode = "UCXL-404-MENTORSHIP_UNAVAILABLE"
CodeProjectNotFound UCXLCode = "UCXL-404-PROJECT_NOT_FOUND"
CodeCollaborationTimeout UCXLCode = "UCXL-408-COLLABORATION_TIMEOUT"
)
// UCXLResponse represents a standardized UCXL success response
type UCXLResponse struct {
Response UCXLResponseData `json:"response"`
}
// UCXLResponseData contains the actual response data
type UCXLResponseData struct {
Code UCXLCode `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
Details interface{} `json:"details,omitempty"`
RequestID string `json:"request_id"`
Timestamp time.Time `json:"timestamp"`
}
// UCXLError represents a standardized UCXL error response
type UCXLError struct {
Error UCXLErrorData `json:"error"`
}
// UCXLErrorData contains the actual error data
type UCXLErrorData struct {
Code UCXLCode `json:"code"`
Message string `json:"message"`
Details interface{} `json:"details,omitempty"`
Source string `json:"source"`
Path string `json:"path"`
RequestID string `json:"request_id"`
Timestamp time.Time `json:"timestamp"`
Cause *UCXLError `json:"cause,omitempty"`
}
// ResponseBuilder helps build standardized UCXL responses
type ResponseBuilder struct {
requestID string
source string
}
// NewResponseBuilder creates a new response builder
func NewResponseBuilder(requestID string, source string) *ResponseBuilder {
if requestID == "" {
requestID = generateRequestID()
}
if source == "" {
source = "ucxi-server"
}
return &ResponseBuilder{
requestID: requestID,
source: source,
}
}
// Success creates a standardized success response
func (rb *ResponseBuilder) Success(code UCXLCode, message string, data interface{}) *UCXLResponse {
return &UCXLResponse{
Response: UCXLResponseData{
Code: code,
Message: message,
Data: data,
RequestID: rb.requestID,
Timestamp: time.Now().UTC(),
},
}
}
// SuccessWithDetails creates a success response with additional details
func (rb *ResponseBuilder) SuccessWithDetails(code UCXLCode, message string, data interface{}, details interface{}) *UCXLResponse {
return &UCXLResponse{
Response: UCXLResponseData{
Code: code,
Message: message,
Data: data,
Details: details,
RequestID: rb.requestID,
Timestamp: time.Now().UTC(),
},
}
}
// Error creates a standardized error response
func (rb *ResponseBuilder) Error(code UCXLCode, message string, path string) *UCXLError {
return &UCXLError{
Error: UCXLErrorData{
Code: code,
Message: message,
Source: rb.source,
Path: path,
RequestID: rb.requestID,
Timestamp: time.Now().UTC(),
},
}
}
// ErrorWithDetails creates an error response with additional details
func (rb *ResponseBuilder) ErrorWithDetails(code UCXLCode, message string, path string, details interface{}) *UCXLError {
return &UCXLError{
Error: UCXLErrorData{
Code: code,
Message: message,
Details: details,
Source: rb.source,
Path: path,
RequestID: rb.requestID,
Timestamp: time.Now().UTC(),
},
}
}
// ErrorWithCause creates an error response with a causal chain
func (rb *ResponseBuilder) ErrorWithCause(code UCXLCode, message string, path string, cause *UCXLError) *UCXLError {
return &UCXLError{
Error: UCXLErrorData{
Code: code,
Message: message,
Source: rb.source,
Path: path,
RequestID: rb.requestID,
Timestamp: time.Now().UTC(),
Cause: cause,
},
}
}
// Convenience methods for common responses
// OK creates a standard 200 OK response
func (rb *ResponseBuilder) OK(data interface{}) *UCXLResponse {
return rb.Success(CodeSuccess, "Request completed successfully", data)
}
// Created creates a standard 201 Created response
func (rb *ResponseBuilder) Created(data interface{}) *UCXLResponse {
return rb.Success(CodeCreated, "Resource created successfully", data)
}
// NoContent creates a standard 204 No Content response
func (rb *ResponseBuilder) NoContent() *UCXLResponse {
return rb.Success(CodeNoContent, "Request completed with no content", nil)
}
// BadRequest creates a standard 400 Bad Request error
func (rb *ResponseBuilder) BadRequest(message string, path string) *UCXLError {
return rb.Error(CodeBadRequest, message, path)
}
// InvalidAddress creates a UCXL-specific invalid address error
func (rb *ResponseBuilder) InvalidAddress(message string, path string, addressDetails interface{}) *UCXLError {
return rb.ErrorWithDetails(CodeInvalidAddress, message, path, map[string]interface{}{
"field": "address",
"address": addressDetails,
})
}
// NotFound creates a standard 404 Not Found error
func (rb *ResponseBuilder) NotFound(message string, path string) *UCXLError {
return rb.Error(CodeNotFound, message, path)
}
// Unprocessable creates a standard 422 Unprocessable Entity error
func (rb *ResponseBuilder) Unprocessable(message string, path string, validationErrors interface{}) *UCXLError {
return rb.ErrorWithDetails(CodeUnprocessable, message, path, map[string]interface{}{
"validation_errors": validationErrors,
})
}
// InternalError creates a standard 500 Internal Server Error
func (rb *ResponseBuilder) InternalError(message string, path string) *UCXLError {
return rb.Error(CodeInternalError, message, path)
}
// MethodNotAllowed creates a standard 405 Method Not Allowed error
func (rb *ResponseBuilder) MethodNotAllowed(allowedMethods []string, path string) *UCXLError {
return rb.ErrorWithDetails(CodeMethodNotAllowed, "Method not allowed", path, map[string]interface{}{
"allowed_methods": allowedMethods,
})
}
// Collaboration-specific error builders
// InvalidRole creates a UCXL-specific invalid role error
func (rb *ResponseBuilder) InvalidRole(message string, path string, roleDetails interface{}) *UCXLError {
return rb.ErrorWithDetails(CodeInvalidRole, message, path, map[string]interface{}{
"field": "role",
"role_details": roleDetails,
})
}
// ExpertiseNotAvailable creates a UCXL-specific expertise not available error
func (rb *ResponseBuilder) ExpertiseNotAvailable(message string, path string, expertiseDetails interface{}) *UCXLError {
return rb.ErrorWithDetails(CodeExpertiseNotAvailable, message, path, map[string]interface{}{
"requested_expertise": expertiseDetails,
"suggestion": "Try requesting more general expertise or check available experts",
})
}
// ProjectNotFound creates a UCXL-specific project not found error
func (rb *ResponseBuilder) ProjectNotFound(message string, path string, projectID string) *UCXLError {
return rb.ErrorWithDetails(CodeProjectNotFound, message, path, map[string]interface{}{
"field": "project_id",
"project_id": projectID,
"suggestion": "Verify the project ID is correct and accessible",
})
}
// CollaborationTimeout creates a UCXL-specific collaboration timeout error
func (rb *ResponseBuilder) CollaborationTimeout(message string, path string, timeoutDetails interface{}) *UCXLError {
return rb.ErrorWithDetails(CodeCollaborationTimeout, message, path, map[string]interface{}{
"timeout_reason": timeoutDetails,
"suggestion": "Retry the collaboration request or check system load",
})
}
// CollaborationFailed creates a UCXL-specific collaboration failure error
func (rb *ResponseBuilder) CollaborationFailed(message string, path string, failureDetails interface{}) *UCXLError {
return rb.ErrorWithDetails(CodeCollaborationFailed, message, path, map[string]interface{}{
"failure_details": failureDetails,
"suggestion": "Check system status and pubsub connectivity",
})
}
// Helper functions
// GetHTTPStatus maps UCXL codes to HTTP status codes
func GetHTTPStatus(code UCXLCode) int {
switch code {
case CodeSuccess:
return 200
case CodeCreated:
return 201
case CodeAccepted:
return 202
case CodeNoContent:
return 204
case CodeBadRequest, CodeInvalidAddress, CodeInvalidPayload, CodeTemporalInvalid, CodeInvalidRole:
return 400
case CodeUnauthorized:
return 401
case CodeForbidden:
return 403
case CodeNotFound, CodeResolutionFailed, CodeExpertiseNotAvailable, CodeMentorshipUnavailable, CodeProjectNotFound:
return 404
case CodeCollaborationTimeout:
return 408
case CodeMethodNotAllowed:
return 405
case CodeConflict:
return 409
case CodeUnprocessable, CodeNavigationFailed:
return 422
case CodeTooManyRequests:
return 429
case CodeInternalError, CodeStorageFailed, CodeAnnounceFailed, CodeCollaborationFailed:
return 500
case CodeNotImplemented:
return 501
case CodeBadGateway:
return 502
case CodeServiceUnavailable:
return 503
case CodeGatewayTimeout:
return 504
default:
return 500
}
}
// generateRequestID creates a unique request ID
func generateRequestID() string {
// Simple UUID-like generator for request IDs
return time.Now().Format("20060102-150405") + "-" + randomString(8)
}
// randomString generates a random string of the specified length
func 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)
}