converge-core 1.0.0

Converge Agent OS - correctness-first, context-driven multi-agent runtime
Documentation
# Capability Boundary Documentation

This document defines the trait ownership and migration guide for converge-core's
capability boundary traits. These traits form the abstraction layer between
converge-core (correctness axioms) and capability crates (implementations).

## Trait Ownership Table

| Trait | Owner | Module | Purpose | Dyn-Safe |
|-------|-------|--------|---------|----------|
| `CapabilityError` | `converge-core` | `traits::error` | Error classification interface | N/A |
| `ErrorCategory` | `converge-core` | `traits::error` | Error category enumeration | N/A |
| `ChatBackend` | `converge-core` | `traits::llm` | Chat completion (GAT async) | No |
| `EmbedBackend` | `converge-core` | `traits::llm` | Embedding generation (GAT async) | No |
| `LlmBackend` | `converge-core` | `traits::llm` | Chat + Embed umbrella | No |
| `DynChatBackend` | `converge-core` | `traits::llm` | Dyn-safe chat wrapper | Yes |
| `DynEmbedBackend` | `converge-core` | `traits::llm` | Dyn-safe embed wrapper | Yes |
| `RecallReader` | `converge-core` | `traits::recall` | Query-only recall access | No |
| `RecallWriter` | `converge-core` | `traits::recall` | Mutation recall access | No |
| `Recall` | `converge-core` | `traits::recall` | Reader + Writer umbrella | No |
| `DynRecallReader` | `converge-core` | `traits::recall` | Dyn-safe recall reader | Yes |
| `ExperienceAppender` | `converge-core` | `traits::store` | Append-only event storage | No |
| `ExperienceReplayer` | `converge-core` | `traits::store` | Streaming replay access | No |
| `DynExperienceAppender` | `converge-core` | `traits::store` | Dyn-safe appender | Yes |
| `DynExperienceReplayer` | `converge-core` | `traits::store` | Dyn-safe replayer | Yes |
| `Validator` | `converge-core` | `traits::validator` | Proposal validation | No |
| `DynValidator` | `converge-core` | `traits::validator` | Dyn-safe validator | Yes |
| `Promoter` | `converge-core` | `traits::promoter` | Proposal promotion | No |
| `DynPromoter` | `converge-core` | `traits::promoter` | Dyn-safe promoter | Yes |
| `Executor` | `converge-core` | `traits` (inline) | Parallel execution strategy | No |
| `Randomness` | `converge-core` | `traits` (inline) | Random number generation | No |
| `Fingerprint` | `converge-core` | `traits` (inline) | Cryptographic hashing | No |

## Deprecated Traits

| Deprecated Trait | Replacement | Module |
|-----------------|-------------|--------|
| `LlmProvider` | `ChatBackend`, `EmbedBackend` | `llm.rs` -> `traits::llm` |
| `LlmBackend` (backend.rs) | `traits::LlmBackend` | `backend.rs` -> `traits::llm` |
| `ExperienceStore` | `ExperienceAppender`, `ExperienceReplayer` | `experience_store.rs` -> `traits::store` |

## Design Principles

### 1. Split by Capability, Not Provider

Traits are split by capability (chat, embed, recall, store) rather than provider
(OpenAI, Anthropic). This allows:
- Fine-grained authorization boundaries
- Different implementations for different capabilities
- Mixing providers per capability

### 2. GAT Async Pattern

All async traits use Generic Associated Types (GATs) for zero-cost async:

```rust
pub trait ChatBackend: Send + Sync {
    type ChatFut<'a>: Future<Output = Result<ChatResponse, LlmError>> + Send + 'a
    where
        Self: 'a;

    fn chat<'a>(&'a self, req: ChatRequest) -> Self::ChatFut<'a>;
}
```

This avoids the overhead of `async_trait` proc macros and box allocation.

### 3. Dyn-Safe Wrappers

For runtime polymorphism (`dyn Trait`), use the `Dyn*` variants:

```rust
// Static dispatch (zero-cost, compile-time)
fn process<B: ChatBackend>(backend: &B, req: ChatRequest) { ... }

// Dynamic dispatch (runtime, box allocation)
fn process_dyn(backend: &dyn DynChatBackend, req: ChatRequest) { ... }
```

Blanket implementations automatically provide `Dyn*` for any `*` implementor.

### 4. Error Classification

All capability errors implement `CapabilityError` for uniform handling:

```rust
impl CapabilityError for LlmError {
    fn category(&self) -> ErrorCategory { ... }
    fn is_transient(&self) -> bool { ... }
    fn is_retryable(&self) -> bool { ... }
    fn retry_after(&self) -> Option<Duration> { ... }
}
```

This enables generic retry/circuit breaker logic across all capabilities.

## Migration Guide

### From `LlmProvider` to `ChatBackend`

**Before (deprecated):**
```rust
use converge_core::llm::{LlmProvider, LlmRequest, LlmResponse, LlmError};

impl LlmProvider for MyProvider {
    fn name(&self) -> &str { "my-provider" }
    fn model(&self) -> &str { "my-model" }
    fn complete(&self, request: &LlmRequest) -> Result<LlmResponse, LlmError> {
        // Synchronous implementation
    }
}
```

**After (recommended):**
```rust
use converge_core::traits::{ChatBackend, ChatRequest, ChatResponse, LlmError};
use std::future::Future;

impl ChatBackend for MyProvider {
    type ChatFut<'a> = impl Future<Output = Result<ChatResponse, LlmError>> + Send + 'a
    where
        Self: 'a;

    fn chat<'a>(&'a self, req: ChatRequest) -> Self::ChatFut<'a> {
        async move {
            // Async implementation
        }
    }
}
```

### From `LlmBackend` (backend.rs) to `traits::LlmBackend`

**Before (deprecated):**
```rust
use converge_core::backend::{LlmBackend, BackendRequest, BackendResponse, BackendResult};

impl LlmBackend for MyBackend {
    fn name(&self) -> &str { "my-backend" }
    fn supports_replay(&self) -> bool { false }
    fn execute(&self, request: &BackendRequest) -> BackendResult<BackendResponse> {
        // Synchronous implementation
    }
    fn supports_capability(&self, cap: BackendCapability) -> bool { ... }
}
```

**After (recommended):**
```rust
use converge_core::traits::{ChatBackend, EmbedBackend, LlmBackend};

// Implement ChatBackend and EmbedBackend separately
// LlmBackend is automatically implemented via blanket impl
impl ChatBackend for MyBackend { ... }
impl EmbedBackend for MyBackend { ... }
// MyBackend now implements LlmBackend automatically
```

### From `ExperienceStore` to `ExperienceAppender`/`ExperienceReplayer`

**Before (deprecated):**
```rust
use converge_core::experience_store::{ExperienceStore, ExperienceEventEnvelope, EventQuery};

impl ExperienceStore for MyStore {
    fn append_event(&self, event: ExperienceEventEnvelope) -> ExperienceStoreResult<()> { ... }
    fn query_events(&self, query: &EventQuery) -> ExperienceStoreResult<Vec<ExperienceEventEnvelope>> { ... }
    // ...other methods
}
```

**After (recommended):**
```rust
use converge_core::traits::{ExperienceAppender, ExperienceReplayer, StoreError};

// Split into separate traits by capability
impl ExperienceAppender for MyStore {
    type AppendFut<'a> = impl Future<Output = Result<(), StoreError>> + Send + 'a
    where
        Self: 'a;

    fn append<'a>(&'a self, event: ExperienceEventEnvelope) -> Self::AppendFut<'a> {
        async move { ... }
    }
}

impl ExperienceReplayer for MyStore {
    type ReplayFut<'a> = impl Future<Output = Result<ReplayBatch, StoreError>> + Send + 'a
    where
        Self: 'a;

    fn replay<'a>(&'a self, cursor: ReplayCursor, options: ReplayOptions) -> Self::ReplayFut<'a> {
        async move { ... }
    }
}
```

## Type-State Integration (Validator/Promoter)

The `Validator` and `Promoter` traits integrate with the type-state pattern:

```rust
// Validator: Draft -> ValidationReport
impl Validator for MyValidator {
    type ValidateFut<'a> = impl Future<Output = Result<ValidationReport, ValidatorError>> + Send + 'a
    where
        Self: 'a;

    fn validate<'a>(
        &'a self,
        proposal: &'a Proposal<Draft>,
        policy: &'a ValidationPolicy,
    ) -> Self::ValidateFut<'a> { ... }
}

// Promoter: Validated -> Fact
impl Promoter for MyPromoter {
    type PromoteFut<'a> = impl Future<Output = Result<Fact, PromoterError>> + Send + 'a
    where
        Self: 'a;

    fn promote<'a>(
        &'a self,
        proposal: Proposal<Validated>,
        report: &'a ValidationReport,
        context: &'a PromotionContext,
    ) -> Self::PromoteFut<'a> { ... }
}
```

The type system enforces the lifecycle: Draft -> Validated -> Fact.

## Version History

- **v0.2.0**: Added capability boundary traits (`traits/` module)
  - `ChatBackend`, `EmbedBackend`, `LlmBackend` (replaces `LlmProvider`, `backend::LlmBackend`)
  - `RecallReader`, `RecallWriter`, `Recall` (new split design)
  - `ExperienceAppender`, `ExperienceReplayer` (replaces `ExperienceStore`)
  - `Validator`, `Promoter` (new, type-state aware)
  - All traits use GAT async pattern
  - Dyn-safe wrappers for all traits

- **v0.1.0**: Original synchronous traits
  - `LlmProvider` (deprecated)
  - `LlmBackend` in backend.rs (deprecated)
  - `ExperienceStore` (deprecated)