//! # rutster-sim — the self-hostable benchmark + simulation harness
//!
//! **Status:** spearhead step 4½ (ADR-0010). The wedge's measurement surface.
//!
//! This crate drives synthetic callers through the SAME media-leg path real
//! callers use, measures p50/p99 mouth-to-ear latency + barge-in kill-time
//! against slice-4's ≤60 ms kill budget, and runs the same measurements at
//! 1 / 10 / 50 concurrent calls. A separate CI job
//! (`cargo test --all --features=sim-bench`) asserts thresholds per commit;
//! a latency regression fails the build (ADR-0010).
//!
//! # Why this crate exists (the FOB differentiator)
//!
//! Slice-4 ships a reflex loop + a synthetic e2e test. SIM-BENCH is the
//! artifact that turns arithmetic latency claims into CI-regressed
//! measurement. See
//! [`docs/superpowers/specs/2026-07-05-slice-4-half-benchmark-sim-design.md`]
//! for the design.
//!
//! # Why a separate crate (not in-tree tests)
//!
//! The harness is hot-path-adjacent + differentiating (ADR-0008 FOB) — it
//! earns cratehood the same way `rutster-tap` did. The dep direction is
//! clean: `rutster-sim` → `rutster-media` + `rutster`. The harness
//! consumes types; it doesn't ride on the binary's internal plumbing.
//!
//! # Module map (lands across S1-S7)
//!
//! - [`scenario`] (S1) — `Scenario` + `ScenarioStep` TOML-deserializable
//!   scripted-caller data types. Determinism is the point.
//! - [`sim_audio_pipe`] (S2) — `SimAudioPipe: AudioPipe` test-double that
//!   IS the caller; captures both clocks (`Instant::now()` at onset +
//!   receipt). The measurement boundary (spec §2.2).
//! - [`latency`] (S3) — `LatencyProbe`: post-hoc p50/p99 kill + mouth-to-ear
//!   computation from the `Capture` event stream.
//! - [`runner`] (S4) — `SimCall` + `ScenarioRunner`: drives one synthetic
//!   caller end-to-end against the FOB reflex loop standalone in tokio
//!   (no `MediaThread` extension per S4 standalone-path conclusion).
//! - [`concurrency`] (S5) — `ConcurrencyRunner`: N concurrent `SimCall`s
//!   against the same MockRealtimeBrain; aggregates per-call latencies
//!   into a `SweepReport`.
//! - [`tick_lag`] (S6) — `TickLagGauge`: the ADR-0010 doctrine-drift
//!   detector. Surfaces `tick_overruns` / `last_tick_micros` in the
//!   `SweepReport`.
//! - [`thresholds`] (S7) — Threshold consts + the `#[cfg(feature =
//!   "sim-bench")] #[tokio::test]` assertion tests. A latency regression
//!   fails the build.

// All modules declared upfront so the lib.rs is stable across task
// commits; each module file grows from a `//! stub` header to its full
// impl as its task lands. Only the `pub use` re-exports for landed
// modules are present — they grow as each task's symbols become available.
pub mod concurrency;
pub mod latency;
#[cfg(all(test, feature = "sim-bench"))]
mod nodelay;
pub mod runner;
pub mod scenario;
pub mod sim_audio_pipe;
pub mod thresholds;
pub mod tick_lag;

pub use concurrency::{ConcurrencyRunner, PerConcurrencyReport, SweepReport};
pub use latency::LatencyProbe;
pub use runner::{ScenarioRunner, SimCall};
pub use scenario::{Scenario, ScenarioError, ScenarioStep};
pub use sim_audio_pipe::{Capture, SimAudioPipe};
pub use thresholds::{
    BARGE_IN_KILL_TIME_P99_MS, MOUTH_TO_EAR_P99_MS, SWEEP_CONCURRENCIES, TICK_LAG_MAX_MS,
    TICK_OVERRUN_PCT_MAX, WS_FRAME_SEND_TO_RECV_P99_MS,
};
pub use tick_lag::{TickLagGauge, TickLagStats};
