# Platform Configuration Guide
kode-bridge constructors take an endpoint path directly. Environment variables
are an application concern; the checked-in examples use `CUSTOM_SOCK` on Unix
and `CUSTOM_PIPE` on Windows, but the library does not read either variable.
## Endpoint configuration
### Unix
```bash
CUSTOM_SOCK=/tmp/my-service.sock cargo run --example request
```
Use `/tmp` for local development. For a production service, prefer a dedicated
directory such as `/run/my-app` whose ownership and permissions prevent
untrusted path replacement.
```bash
sudo install -d -o myapp -g myapp -m 0750 /run/my-app
CUSTOM_SOCK=/run/my-app/api.sock cargo run --example request
```
Unix endpoints may be relative or absolute file-system paths, but cannot
contain an interior NUL. The parent directory must already exist.
### Windows
Command Prompt:
```cmd
set CUSTOM_PIPE=\\.\pipe\my-service
cargo run --example request
```
PowerShell:
```powershell
$env:CUSTOM_PIPE='\\.\pipe\my-service'
cargo run --example request
```
Windows endpoints must use `\\HOST\pipe\NAME`. kode-bridge servers reject
remote clients, so use the local `\\.\pipe\NAME` form.
### `.env` examples
Unquoted `.env` values do not need Rust string-literal escaping:
```env
# Unix
CUSTOM_SOCK=/tmp/my-service.sock
# Windows
CUSTOM_PIPE=\\.\pipe\my-service
```
The examples call `dotenvy::dotenv()` before reading these values. Add
`dotenvy` to your own application if you want the same behavior.
## HTTP client configuration
`ClientConfig` contains a nested `PoolConfig`; the older flattened
`pool_max_size` and `pool_min_idle` fields do not exist.
```rust
use kode_bridge::{pool::PoolConfig, ClientConfig, IpcHttpClient};
use std::time::Duration;
let pool = PoolConfig {
max_size: 16,
min_idle: 4,
max_idle_time_ms: 30_000,
connection_timeout_ms: 5_000,
retry_delay_ms: 25,
max_retries: 3,
max_concurrent_requests: 16,
max_requests_per_second: None,
};
let config = ClientConfig {
default_timeout: Duration::from_secs(5),
pool_config: pool,
enable_pooling: true,
max_retries: 3,
retry_delay: Duration::from_millis(25),
max_concurrent_requests: 16,
max_requests_per_second: Some(50.0),
};
let client = IpcHttpClient::with_config(endpoint, config)?;
```
Choose pool limits from measured concurrent demand. A larger pool consumes more
open handles and memory and does not guarantee lower latency.
## Streaming client configuration
```rust
use kode_bridge::{IpcStreamClient, StreamClientConfig};
use std::time::Duration;
let config = StreamClientConfig {
default_timeout: Duration::from_secs(60),
max_retries: 3,
retry_delay: Duration::from_millis(100),
buffer_size: 16 * 1024,
};
let client = IpcStreamClient::with_config(endpoint, config)?;
```
The buffer size is a user-space read buffer, not the Windows named-pipe kernel
buffer size. Measure memory and throughput before increasing it broadly.
## HTTP server configuration
```rust
use kode_bridge::ServerConfig;
use std::time::Duration;
let config = ServerConfig {
max_connections: 128,
read_timeout: Duration::from_secs(5),
write_timeout: Duration::from_secs(5),
max_request_size: 10 * 1024 * 1024,
max_header_size: 4096,
enable_logging: true,
max_requests_per_connection: 32,
shutdown_timeout: Duration::from_secs(3),
};
```
`read_timeout` bounds waiting for and parsing the next request. Despite its
name, `write_timeout` currently bounds the handler future; the subsequent
response send does not have a separate server-side timeout in version 0.5.
## Listener options
### Unix cleanup, overwrite, and mode
```rust
#[cfg(unix)]
let options = kode_bridge::ListenerOptions::new()
.reclaim_name(true)
.try_overwrite(true)
.max_spin_time(std::time::Duration::from_millis(100));
#[cfg(all(unix, not(target_os = "macos")))]
let options = options.mode(0o660);
```
- `reclaim_name(true)` is the default.
- `try_overwrite(false)` is the default.
- Explicit overwrite refuses non-socket paths and live listeners.
- Custom mode currently returns `Unsupported` on macOS.
- Use a trusted parent directory because metadata-check then remove is not an
atomic compare-and-delete operation.
### Windows SDDL
```rust
#[cfg(windows)]
let options = kode_bridge::ListenerOptions::new()
.security_descriptor("D:(A;;GA;;;WD)");
```
The descriptor is parsed when configuring the builder and applied to every
pipe instance. Invalid SDDL panics for compatibility with the 0.4 API. Prefer a
least-privilege descriptor; `WD` grants access to Everyone and should not be a
copy-paste production default.
## Operational checks
- Confirm the client and server resolve exactly the same endpoint string.
- Ensure the Unix socket parent exists and has the intended ownership.
- Treat `Address already in use` as a live-listener or stale-path decision;
enable overwrite only when that policy is intentional.
- On Windows, distinguish an absent pipe from `ERROR_PIPE_BUSY`; kode-bridge
waits asynchronously for busy instances. High-level requests apply their
request timeout, while direct stream connects and preheating need an
application-owned cancellation boundary.
- Exercise service identity and ACL behavior with the actual privileged and
unprivileged accounts used in production.
## Benchmark configuration
```bash
cargo bench --all-features --bench bench_version
cargo bench --all-features --bench ipc_transport
```
Criterion results are machine-specific. Keep the endpoint generator, payload,
sample parameters, toolchain, and host unchanged when comparing versions.