Skip to main content

amberfork_record/
lib.rs

1//! The record path: wrap an agent, capture what crossed the provider boundary.
2//!
3//! amberfork has two ingestion paths sharing one canonical model (design doc, "Counterfactual
4//! attribution is impossible against passive OTLP alone"). The PASSIVE path aligns OTel traces
5//! you already have — framework-agnostic, but content is opt-in and often absent, and you
6//! cannot re-run a telemetry photo. This crate is the RECORD path: it runs the agent behind a
7//! local capture proxy, so content is guaranteed and the run stays re-executable.
8//!
9//! Two things follow from that, and they are the reason this crate exists rather than being a
10//! flag on `ingest`:
11//! - **Full content.** The passive path's `full content guaranteed` cell is "no"; this path's
12//!   is "yes". Full *inputs* are worth +76% relative step-level accuracy over output-only logs
13//!   ("Replay fidelity ceiling"), which improves the ordinary diff before any re-execution
14//!   exists.
15//! - **Re-executability.** A boundary recording can be replayed and mutated, which is what
16//!   counterfactual attribution needs. This crate captures; re-execution is its consumer.
17//!
18//! `tokio` lives here because this is an I/O edge, alongside `amberfork-server`. Engine crates
19//! stay sync and pure.
20
21mod cassette;
22mod normalize;
23mod proxy;
24
25pub use cassette::{
26    Body, CapturedRequest, CapturedResponse, Cassette, CassetteVersion, Exchange,
27    retain_request_headers, retain_response_headers,
28};
29pub use normalize::{normalize, normalize_str};
30pub use proxy::{CaptureProxy, RecordError};