nerve-ipc 0.2.0

Binary framing protocol for local IPC over Unix Domain Sockets
Documentation
# NERVE

A binary, local-only, low-latency IPC protocol for browser-internal intelligence.

## Overview

NERVE is a specialized protocol designed to connect browser components (search, local LLMs, system services) as if they were part of a single nervous system. It prioritizes deterministic latency, minimal allocations, streaming-first semantics, and immediate cancellation over a Unix Domain Socket.

**Status:** v0.2.0 (active development — v0.x allows breaking changes between releases)

### Key Characteristics

- **Binary Protocol**: Fixed-size frame headers with little-endian encoding
- **Local IPC Only**: Designed for Unix Domain Sockets (UDS), single-machine communication
- **Low Latency**: Fixed-size frame headers, single-pass parsing, minimal allocation path
- **Streaming First**: Supports multi-frame responses with ordered delivery guarantees
- **Immediate Cancellation**: Best-effort request termination
- **Predictable**: Single-pass parsing, fixed limits, clear error semantics

## What NERVE is NOT

- A general-purpose RPC protocol
- Suitable for remote/network transport
- Backward compatible (v0.x allows breaking changes)
- Including authentication or encryption (assumes local trust boundary)

## Installation

Add to your `Cargo.toml`:

```toml
[dependencies]
nerve-ipc = "0.2"
```

Or via `cargo add`:

```bash
cargo add nerve-ipc
```

## Project Structure

```
nerve/
├── Cargo.toml              # Rust project manifest
├── src/
│   ├── lib.rs             # Library root
│   ├── codec.rs           # Frame encoding/decoding
│   ├── constants.rs       # Protocol constants
│   ├── error.rs           # Error types
│   ├── frame.rs           # Frame format & layout
│   ├── io.rs              # I/O operations
│   ├── message.rs         # Message type definitions
│   ├── request.rs         # Request lifecycle
│   └── types.rs           # Shared type definitions
├── examples/
│   └── ping.rs            # Encode/decode roundtrip example
├── benches/
│   └── ping.rs            # Performance benchmarks
├── tests/
│   ├── frame_roundtrip.rs # Frame encoding tests
│   └── malformed.rs       # Malformed input handling
└── docs/
    └── protocol.md        # Full protocol specification
```

## Protocol Basics

### Frame Format

Every message is wrapped in a binary frame:

```
Header (20 bytes fixed):
  magic (u32)        → 0x4E455256 ("NERV")
  version (u16)      → 1
  type (u8)          → Message type
  flags (u8)         → Bitflags (STREAM, FINAL)
  request_id (u64)   → Unique per request
  payload_len (u32)  → Payload size in bytes

Payload (0 to 1 MiB):
  implementation-defined binary data
```

### Message Types

| Type  | Name          | Direction       | Purpose                                 |
|-------|---------------|-----------------|------------------------------------------|
| 0x01  | PING          | bidirectional   | Latency measurement & connection health |
| 0x02  | SEARCH_QUERY  | client → server | Initiate search                         |
| 0x03  | SEARCH_RESULT | server → client | Stream search results                   |
| 0x04  | AI_TOKEN      | server → client | Stream LLM tokens                       |
| 0x05  | CANCEL        | client → server | Request termination                     |

### Limits

| Limit                  | Value                  |
|------------------------|------------------------|
| Max payload per frame  | 1 MiB                  |
| Max in-flight requests | 1024                   |
| Frame rate             | Implementation-defined |

Frames exceeding limits trigger immediate connection termination.

## Quick Start

```rust
use nerve_ipc::{
    codec::{encode, decode},
    types::{FrameFlags, MessageType, RequestId},
};

let encoded = encode(
    MessageType::Ping,
    FrameFlags::empty(),
    RequestId(1),
    &[],
)?;

let frame = decode(&encoded)?;
println!("msg_type=0x{:02X}", frame.header.msg_type);
```

Run the included example:

```bash
cargo run --example ping
```

## Benchmarks

NERVE protocol framing is designed for low-latency local IPC.

### Ping Roundtrip (Encode + Decode)

Environment:
- Rust `--release`
- Single-threaded
- In-memory buffer
- No I/O

Benchmark:
```
nerve_ping_roundtrip
time: [19.419 ns 19.511 ns 19.603 ns]
```

This measures the full frame encode + zero-copy decode path.

## Prerequisites

- Rust 1.85+ (required for edition 2024)
- Unix-like OS (Linux, macOS) for UDS support

## Build

```bash
cargo build
```

## Run Tests

```bash
cargo test
```

## Run Benchmarks

```bash
cargo bench
```

## Protocol Compliance

An implementation is NERVE v0.2.0 compliant if it:

- Implements the frame format exactly
- Enforces all hard limits
- Supports all message types
- Handles malformed input safely (close connection)
- Does not deadlock on cancellation

## Error Handling

Protocol violations result in local error handling; no error frames are transmitted in v0.1.0.

**Error Classes:**

- `ProtocolViolation`: Invalid frame or state transition
- `UnsupportedVersion`: Version mismatch
- `MalformedFrame`: Unparseable header or payload
- `PayloadTooLarge`: Exceeds MAX_PAYLOAD_SIZE
- `InternalError`: Implementation-specific failure

**Response to Errors:**

- Malformed frames → immediate connection close
- Unsupported version → immediate connection close
- Protocol violations → log + close connection

## Documentation

Full protocol specification: [docs/protocol.md](docs/protocol.md)
File-level overview: [docs/files.md](docs/files.md)

## Security Model

- **Trust Boundary**: Local user on the same machine
- **Transport**: Unix Domain Sockets (implicit local-only)
- **Authentication**: None in v0.1.0 (socket file permissions enforce access)
- **Encryption**: None in v0.1.0 (can be added at application layer)

## Contributing

Issues and pull requests are welcome via the [repository](https://github.com/anvesha-systems/nerve).

## License

Licensed under either of

- [Apache License, Version 2.0]LICENSE-APACHE
- [MIT License]LICENSE-MIT

at your option.