1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//! Counterfactual attribution: verify a fork by re-running the agent, not just observing it.
//!
//! `amberfork diff` localizes the fork and labels attribution `Static` — a structural claim
//! ("they diverge here, and it propagates downstream") that no re-execution ever checked. This
//! crate is the consumer the record/replay path was built for (epic #35): it patches the fork
//! step with the good run's behaviour, re-drives the agent through [`amberfork_replay`] against
//! the patched cassette, and reports whether the run *recovered* — the difference between "they
//! differ here" and "this is what broke it".
//!
//! It is the one crate that turns [`AttributionMode::Counterfactual`](amberfork_model::AttributionMode)
//! — defined in the frozen model but produced nowhere — into real output.
//!
//! ## Offline by default, opt-in to re-execute
//!
//! Nothing here runs unless the CLI is invoked with `--verify`: default `amberfork diff` stays
//! 100% offline and structural. Re-execution needs a live provider seam and a re-runnable agent
//! command, both injected by the caller; the whole test suite substitutes an in-process stub for
//! each, so `cargo test --workspace` stays offline and deterministic.
//!
//! ## Shape of the pipeline
//!
//! ```text
//! DiffResult + bad/good cassettes
//! └─ patch_cassette (pure) → the bad cassette with the fork step's response swapped
//! └─ re-execute × N (I/O) → each re-run's own cassette, via ReplayServer + the agent
//! └─ recovery oracle (pure) → recovered / not recovered / inconclusive, per run
//! └─ consensus over N (pure) → Recovery tri-state → upgraded Attribution
//! ```
//!
//! [`verify`] is the entry that runs the whole pipeline; the CLI wires it behind `diff --verify`.
pub use ;
pub use patch_cassette;
pub use verify;