# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## What is Knafeh?

Knafeh is a QUIC-based RPC framework implemented in Rust with Python bindings via PyO3. It provides two transport backends: raw QUIC (quinn, for maximum throughput) and HTTP/3 (tokio-quiche, for gRPC compatibility). Features include pluggable codecs (default: Protobuf, with JSON available), gRPC-compatible status codes, an interceptor middleware system, server-streaming RPC, and connection pooling. The Python API uses native async via pyo3-async-runtimes (asyncio-compatible), with both async (`Client`) and sync (`SyncClient`) interfaces.

## Build & Test Commands

```bash
# Rust
cargo build                        # Debug build
cargo build --release              # Release build
cargo test --no-default-features   # Run all Rust tests (pure-Rust, no Python)
cargo test <test_name>             # Run a single Rust test
cargo run --no-default-features --example rust_server  # Run Rust server example

# Python (requires maturin, Python >= 3.13)
PYO3_USE_ABI3_FORWARD_COMPATIBILITY=1 maturin develop  # Build and install Python extension
pytest tests/test_knafeh.py        # Run Python binding tests
pytest tests/test_e2e_python.py    # Run Python E2E tests (starts real QUIC servers)

# E2E tests (TLS certs are generated at runtime via rcgen)
cargo test --no-default-features --test e2e_test           # Core + streaming tests
cargo test --no-default-features --test e2e_resilience_test # Retry + error tests
cargo test --no-default-features --test e2e_load_test      # Load simulation tests

# Performance benchmarks (release mode, 10K+ requests)
cargo test --no-default-features --release --test e2e_perf_test -- --ignored --nocapture
```

**Note:** Use `--no-default-features` to disable the `python` Cargo feature when running Rust tests without a Python environment.

## Architecture

### Transport layer

Knafeh offers two transport backends:

- **Raw QUIC** (`transport/quic_native.rs`) — Uses quinn (pure Rust, rustls). Opens bidirectional QUIC streams per RPC call with a minimal length-prefixed wire protocol (`transport/quic_wire.rs`). ~13K rpc/s sequential, ~104K rpc/s parallel. No HTTP overhead.
- **HTTP/3** (`server/mod.rs`, `client/mod.rs`) — Uses tokio-quiche (Cloudflare quiche, BoringSSL). Full HTTP/3 with headers, pseudo-headers, content-type. ~4K rpc/s sequential, ~15K rpc/s parallel. gRPC-compatible. The ~3x gap vs raw QUIC is structural (3 mutex locks + event-loop dispatch + task spawn per response).

### Layered design (Rust core -> PyO3 FFI -> Python wrappers)

**Rust core** (`src/`):
- `transport/` — QUIC (quinn) and HTTP/3 (tokio-quiche) backends, TLS config, wire protocol
- `codec/` — `Codec` trait + Protobuf (default, via prost) and JSON implementations
- `rpc/` — `RpcRequest`, `RpcResponse`, `RpcStatus`, `Metadata`, `Service` trait, `MethodRouter`, `Interceptor` + `MiddlewareStack`, streaming support
- `server/` — `ServerBuilder`, request handler, connection pool, `serve_with_ready_signal()`, server-streaming dispatch
- `client/` — `ClientBuilder`, QUIC connection pool with background event loop, response demux, `RetryPolicy` with exponential backoff + status-code retries
- `error.rs` — `KnafehError` enum (Transport, Codec, Service, Timeout, InvalidMessage, ConnectionClosed, Tls, Io)

**PyO3 FFI layer** (`src/python/`):
- Native async via `pyo3-async-runtimes` — `future_into_py` returns Python awaitables directly
- `RpcClient` with `call()` (async), `call_sync()` (blocking), `server_stream()` (async), `server_stream_sync()` (blocking)
- `RpcServer` with `start()` (async)
- `StreamReceiver` (async) and `SyncStreamReceiver` (blocking, iterable)
- `KnafehError` maps to Python exceptions

**Python wrappers** (`python/knafeh/`):
- `client.py` — `Client` (async, anyio TaskGroup for `call_many`) and `SyncClient` (blocking)
- `server.py` — `Server` with `@service` decorator for method registration
- `middleware.py` — Python `Interceptor` base class

### Key traits

- `Service` — Async service handler with method descriptors (unary/server-streaming)
- `Codec` — Encode/decode message payloads (Protobuf default, JSON available)
- `Interceptor` — Request/response middleware chain

### Feature flags

The `python` Cargo feature (enabled by default) gates PyO3 and pyo3-async-runtimes dependencies. Disable with `--no-default-features` for pure-Rust usage.

## Dependencies

See `Cargo.toml` for Rust dependencies (quinn, tokio-quiche, prost, pyo3 0.28, pyo3-async-runtimes 0.28), `pyproject.toml` for Python (anyio >= 4.0, Python >= 3.13). The Python wheel is built with [maturin](https://github.com/PyO3/maturin).
