# UCXL Standard Response and Error Codes Library

This repository contains standardized UCXL error and response codes libraries for **Rust**, **Go**, and **Python** to ensure consistent cross-service communication and client handling across all UCXL implementations.

## Overview

The UCXL codes standard provides:
- **Unified error signaling** across UCXL services (UCXI, Browser, BZZZ, etc.)
- **Machine-readable error codes** with structured payloads
- **Client guidance** for retry logic and error handling
- **Cross-language compatibility** with identical APIs

## Standard Format

### Error Codes
Format: `UCXL-<HTTP-class>-<SHORT_NAME>`

Examples:
- `UCXL-400-INVALID_ADDRESS` - Malformed UCXL URI
- `UCXL-404-NOT_FOUND` - Resource not found
- `UCXL-503-SERVICE_UNAVAILABLE` - Service temporarily unavailable

### Response Codes
Format: `UCXL-<HTTP-class>-<SHORT_NAME>`

Examples:
- `UCXL-200-OK` - Successful request
- `UCXL-201-CREATED` - Resource created
- `UCXL-202-ACCEPTED` - Async operation accepted

## Error Payload Schema

```json
{
  "error": {
    "code": "UCXL-400-INVALID_ADDRESS",
    "message": "Invalid UCXL address format",
    "details": {
      "field": "address",
      "provided": "ucxl://invalid/address",
      "expected_format": "ucxl://<agent>:<role>@<project>:<task>[/<temporal>/<path>]"
    },
    "source": "ucxl-browser/v1",
    "path": "/resolve",
    "request_id": "req-12345",
    "timestamp": "2025-08-09T16:22:20Z",
    "cause": "parse_error"
  }
}
```

## Success Payload Schema

```json
{
  "response": {
    "code": "UCXL-200-OK",
    "message": "Request completed successfully",
    "data": {
      "items": [{"id": "item-1", "name": "Alpha"}]
    },
    "details": {
      "count": 1
    },
    "request_id": "req-12345",
    "timestamp": "2025-08-09T16:22:20Z"
  }
}
```

## Language Implementations

### Rust (`ucxl_codes.rs`)

```rust
use ucxl_core::*;

// Create error response
let error = UCXLErrorBuilder::new(UCXLErrorCode::InvalidAddress)
    .field("address", "ucxl://invalid".into())
    .expected_format("ucxl://<agent>:<role>@<project>:<task>")
    .source("my-service")
    .path("/resolve")
    .build();

// Create success response
let success = UCXLResponseBuilder::new(UCXLResponseCode::Ok)
    .data(serde_json::json!({"result": "success"}))
    .build();

// Check error properties
if error.error.code.should_retry() {
    // Implement retry logic
}
```

### Go (`ucxl_codes.go`)

```go
package main

import (
    "fmt"
    "your-module/ucxl_codes"
)

func main() {
    // Create error response
    error := ucxl_codes.NewErrorBuilder(ucxl_codes.ErrorInvalidAddress).
        Field("address", "ucxl://invalid").
        ExpectedFormat("ucxl://<agent>:<role>@<project>:<task>").
        Source("my-service").
        Path("/resolve").
        Build()

    // Create success response
    success := ucxl_codes.NewResponseBuilder(ucxl_codes.ResponseOK).
        Data(map[string]interface{}{"result": "success"}).
        Build()

    // Check error properties
    if error.Error.Code.ShouldRetry() {
        // Implement retry logic
    }
}
```

### Python (`ucxl_codes.py`)

```python
from ucxl_codes import UCXLErrorBuilder, UCXLErrorCode, UCXLResponseBuilder, UCXLResponseCode

# Create error response
error = UCXLErrorBuilder(UCXLErrorCode.INVALID_ADDRESS) \
    .field("address", "ucxl://invalid") \
    .expected_format("ucxl://<agent>:<role>@<project>:<task>") \
    .source("my-service") \
    .path("/resolve") \
    .build()

# Create success response
success = UCXLResponseBuilder(UCXLResponseCode.OK) \
    .data({"result": "success"}) \
    .build()

# Check error properties
if error.error.code.should_retry():
    # Implement retry logic
    pass
```

## Complete Error Code Reference

| Code | HTTP | Description | Retry? |
|------|------|-------------|--------|
| `UCXL-400-INVALID_ADDRESS` | 400 | Malformed UCXL URI | No |
| `UCXL-400-MISSING_FIELD` | 400 | Required field missing | No |
| `UCXL-400-INVALID_FORMAT` | 400 | Input format invalid | No |
| `UCXL-401-UNAUTHORIZED` | 401 | Authentication required | No |
| `UCXL-403-FORBIDDEN` | 403 | Insufficient permissions | No |
| `UCXL-404-NOT_FOUND` | 404 | Resource not found | No |
| `UCXL-409-CONFLICT` | 409 | State conflict | No |
| `UCXL-422-UNPROCESSABLE_ENTITY` | 422 | Business rule violation | No |
| `UCXL-429-RATE_LIMIT` | 429 | Rate limiting active | **Yes** |
| `UCXL-500-INTERNAL_ERROR` | 500 | Unhandled server error | **Yes** |
| `UCXL-503-SERVICE_UNAVAILABLE` | 503 | Service down/maintenance | **Yes** |
| `UCXL-504-GATEWAY_TIMEOUT` | 504 | Downstream timeout | **Yes** |

## Complete Response Code Reference

| Code | HTTP | Description | Use Case |
|------|------|-------------|----------|
| `UCXL-200-OK` | 200 | Successful request | Standard operations |
| `UCXL-201-CREATED` | 201 | Resource created | POST/PUT create |
| `UCXL-202-ACCEPTED` | 202 | Async operation accepted | Long-running tasks |
| `UCXL-204-NO_CONTENT` | 204 | Success, no content | DELETE operations |
| `UCXL-206-PARTIAL_CONTENT` | 206 | Partial results | Paginated responses |
| `UCXL-304-NOT_MODIFIED` | 304 | Not changed since last fetch | Caching |

## Client Implementation Guidance

### Retry Logic
```rust
fn should_retry_request(error_code: UCXLErrorCode, attempt: u32) -> bool {
    error_code.should_retry() && attempt < MAX_RETRIES
}

async fn execute_with_retry<T>(operation: impl Fn() -> Result<T, UCXLErrorCode>) -> Result<T, UCXLErrorCode> {
    let mut attempt = 0;
    loop {
        match operation() {
            Ok(result) => return Ok(result),
            Err(error) if should_retry_request(error, attempt) => {
                let backoff = Duration::from_millis(100 * 2_u64.pow(attempt));
                tokio::time::sleep(backoff).await;
                attempt += 1;
            },
            Err(error) => return Err(error),
        }
    }
}
```

### Error Classification
```rust
fn classify_error(error: &UCXLErrorCode) -> ErrorCategory {
    if error.is_client_error() {
        ErrorCategory::ClientError // Fix input, don't retry
    } else if error.should_retry() {
        ErrorCategory::RetryableServerError // Retry with backoff
    } else {
        ErrorCategory::PermanentServerError // Don't retry
    }
}
```

### Response Handling
```rust
fn handle_response(response: UCXLResponseCode) -> ActionRequired {
    if response.is_async() {
        ActionRequired::Poll // Poll for completion
    } else if response.is_partial() {
        ActionRequired::Paginate // Fetch remaining data
    } else {
        ActionRequired::None // Complete response
    }
}
```

## Integration with BZZZ

The BZZZ Gateway has been updated to use standardized UCXL codes:

```rust
// BZZZ now returns standardized errors
let error_response = create_error_response(
    UCXLErrorCode::ServiceUnavailable,
    "/bzzz/store",
    Some(&request_id)
);

// DHT operations use standard codes
let not_found = create_envelope_error(
    UCXLErrorCode::NotFound,
    &envelope_id,
    "/dht/retrieve"
);
```

## Testing

Each implementation includes comprehensive tests:

**Rust:**
```bash
cargo test --lib ucxl_codes
```

**Go:**
```bash
go test ./ucxl_codes
```

**Python:**
```bash
python -m pytest ucxl_codes.py -v
# Or run inline tests:
python ucxl_codes.py
```

## Governance and Versioning

- **Version:** 1.0 (following UCXL-ERROR-CODES.md specification)
- **Registry:** Machine-readable definitions in `error-codes.yaml` (future)
- **Deprecation Policy:** New codes added in minor versions, deprecated codes marked but maintained for compatibility
- **Updates:** Changes published with changelog and migration guidance

## Future Enhancements

1. **Machine-readable registry** (`error-codes.yaml`) for code generation
2. **OpenAPI integration** for automatic client generation
3. **Observability integration** with tracing and metrics
4. **Additional language support** (JavaScript/TypeScript, C#, etc.)

## Contributing

When adding new error codes:
1. Follow the `UCXL-<HTTP-class>-<SHORT_NAME>` format
2. Add to all three language implementations
3. Update this documentation
4. Include appropriate tests
5. Ensure retry logic is correctly classified

## License

This UCXL codes library follows the same license as the UCXL project.