parlov-probe 0.3.0

Probe engine trait and HTTP execution layer for parlov.
Documentation
# parlov-probe

HTTP probe execution for parlov. Sends requests, captures the full response surface with timing.

## trait

```rust
pub trait Probe: Send + Sync {
    fn execute(&self, def: &ProbeDefinition)
        -> impl Future<Output = Result<ProbeExchange, Error>> + Send;
}
```

One call, one HTTP interaction, one `ProbeExchange` (paired request + response). The caller drives batching and sample collection. Request context is preserved alongside the response for downstream differential analysis.

## use it

```rust
use parlov_probe::http::HttpProbe;
use parlov_probe::Probe;
use parlov_core::ProbeDefinition;
use http::{Method, HeaderMap};

let client = HttpProbe::new();
let exchange = client.execute(&ProbeDefinition {
    url: "https://api.example.com/users/123".into(),
    method: Method::GET,
    headers: HeaderMap::new(),
    body: None,
}).await?;

println!("status: {}", exchange.response.status);
println!("timing: {}ms", exchange.response.timing_ns / 1_000_000);
```

On native targets, `HttpProbe` uses `reqwest` with connection pooling. On `wasm32-unknown-unknown` (Cloudflare Workers), the same `HttpProbe` API routes through `worker::Fetch` from the Cloudflare Workers Rust SDK — the conversion preserves multi-valued headers (`Set-Cookie`, `WWW-Authenticate`, `Cache-Control`). Timing is measured via `std::time::Instant` around the request-to-response path. All headers from `ProbeDefinition` are forwarded — auth context is expressed as a plain `Authorization` header.

`HttpProbe` derives `Clone`. Cloning is `O(1)` — the inner client is `Arc`-backed — so a single configured instance can be shared across concurrent probe loops without re-initializing the connection pool. `HttpProbe::with_client(reqwest::Client)` accepts a caller-supplied client when non-default configuration is needed (custom redirect policy, pinned TLS roots, timeouts).

## custom probes

Implement `Probe` for custom execution strategies (e.g. HTTP/2 single-packet timing, mTLS client certs):

```rust
struct MyProbe { /* ... */ }

impl Probe for MyProbe {
    fn execute(&self, def: &ProbeDefinition)
        -> impl Future<Output = Result<ProbeExchange, Error>> + Send
    {
        async { todo!() }
    }
}
```

## license

MIT OR Apache-2.0