Files
CHORUS/pkg/ucxl/codes.go
anthonyrawlins 543ab216f9 Complete BZZZ functionality port to CHORUS
🎭 CHORUS now contains full BZZZ functionality adapted for containers

Core systems ported:
- P2P networking (libp2p with DHT and PubSub)
- Task coordination (COOEE protocol)
- HMMM collaborative reasoning
- SHHH encryption and security
- SLURP admin election system
- UCXL content addressing
- UCXI server integration
- Hypercore logging system
- Health monitoring and graceful shutdown
- License validation with KACHING

Container adaptations:
- Environment variable configuration (no YAML files)
- Container-optimized logging to stdout/stderr
- Auto-generated agent IDs for container deployments
- Docker-first architecture

All proven BZZZ P2P protocols, AI integration, and collaboration
features are now available in containerized form.

Next: Build and test container deployment.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-02 20:02:37 +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)
}