proxima-lib 0.1.0

A sans-IO core where everything is a Pipe — one async In -> Result<Out, Err> trait worn four ways (transform, source, sink, observe), composed into proxies, gateways, caches, codecs and telemetry pipelines. Config-driven, runtime-agnostic: the same pipe runs on the from-scratch Prime per-core runtime, on tokio, or on no_std bare metal.
# traces

A span observes an operation's *scope*, and that scope survives an async boundary — and, given the
context explicitly, a plain same-scope call too.

## Builds on

[transform](../transform/README.md) — a span is the observe form over an operation's scope, the same way an observe pipe is that form over a single value.

## What it demonstrates

A span is `Pipe`'s observe form (`In = Out`) aimed at *duration and place in
the request tree* instead of a single value: it wraps `start..end` around an
operation and records where that operation sits relative to its caller.

proxima keeps that "where it sits" fact as **explicit data** — a W3C
`traceparent` (`trace_id` + `span_id`), captured with
`RecorderSpanGuard::inject` and reopened on the other side with
`Recorder::span_from_traceparent`. There is no ambient/thread-local "current
span" the way `tracing` has; nothing reads a parent for you. That's a
deliberate design choice, not just a gap: proxima's own use case is many
concurrently-interleaved requests sharing one executor thread, where a naive
thread-local push/pop span stack would corrupt across tasks (task A opens a
span, awaits and yields the thread, task B runs on the same thread and would
see A's still-pushed span as its own parent).

The example proves both directions of that rule on one call:

- `handle_request` opens its span by hand — `recorder.span(name)...start()`,
  the exact `Recorder::span`/`RecorderSpanGuard` chain `#[instrument]` itself
  expands to — captures its own context into a `HeaderList`, hands the
  captured bytes across a `tokio::spawn` boundary (a different task, possibly
  a different OS thread), and only closes after the spawned `run_query`
  returns. `run_query` reopens its span from the handed-in `traceparent` via
  `span_from_traceparent` — same `trace_id`, `parent_span_id` set to
  `handle_request`'s `span_id`. The context survived the boundary because it
  was carried, not because it was ambient.
- `validate_request` is instrumented with the `#[proxima::telemetry::instrument]`
  sugar and an explicit `parent = parent` argument (`parent: Option<&[u8]>`),
  called TWICE from inside `handle_request`'s scope: once with `parent = None`
  (nothing carried) — its own fresh `trace_id`, no auto-parent, proving the
  sugar form still never nests on its own — and once with the parent's own
  captured `traceparent` bytes threaded through explicitly — same `trace_id`
  as `handle_request`, `parent_span_id` set. Nesting the sugar form in
  wall-clock scope does nothing by itself; passing `parent = <expr>` is what
  connects it — and when it resolves to `Some`, the macro expands to the SAME
  `recorder.span_from_traceparent(name, bytes)...start()` call `run_query`
  makes by hand above. The sugar and the hand-written path are one mechanism,
  not two.

Both facts are asserted against the spans an `InMemoryPipe` actually
captured, not just printed.

## Run

```
cargo run --example traces
```

## What you'll see

```
proxima traces: spans across an async boundary

handle_request: opened span Some(SpanId([...]))
  run_query:      opened span Some(SpanId([...])), carried in from handle_request

handle_request -> 42

span tree (4 spans captured):
  name=validate_request  trace_id=02eb0d43...  span_id=e2e58541...  parent_span_id=-
  name=validate_request  trace_id=603f9a63...  span_id=6d258398...  parent_span_id=89bda28a...
  name=run_query         trace_id=603f9a63...  span_id=2a3349ea...  parent_span_id=89bda28a...
  name=handle_request    trace_id=603f9a63...  span_id=89bda28a...  parent_span_id=-

-> run_query IS a child of handle_request: same trace_id, parent_span_id set
-> validate_request(parent = None) is its OWN root: no context carried, no auto-parent
-> validate_request(parent = Some(..)) IS a child: the explicit seam connects it

PASS: span context survives both the tokio::spawn boundary and a same-scope call,
      via explicit data in both cases -- never ambient.
```

`run_query` and `handle_request` share one `trace_id`, and `run_query`'s
`parent_span_id` equals `handle_request`'s `span_id` — proof the tree
survived `tokio::spawn`. The first `validate_request` call (`parent = None`)
carries a different `trace_id` and no parent at all — proof the
`#[instrument]` sugar never auto-nests on its own, even when called from
inside another span's live scope. The second `validate_request` call
(`parent = Some(traceparent)`) shares `handle_request`'s `trace_id` and
records its `span_id` as parent — proof the explicit `parent = <expr>`
argument is what connects it.