pub struct RefreshLedgerEvidenceComparison {
pub phase_deltas: Vec<RefreshPhaseDelta>,
pub aggregate_duration_delta_pct: Option<f64>,
pub aggregate_throughput_delta_pct: Option<f64>,
pub dominant_phase_shift: Option<(RefreshPhase, RefreshPhase)>,
}Expand description
Cross-run comparison summary suitable for benchmark CI gates and
regression dashboards. Computed by
RefreshLedgerEvidence::compare_to.
Fields§
§phase_deltas: Vec<RefreshPhaseDelta>Per-phase delta for every phase that ran in EITHER side. Phases unique to one side surface with a zero on the missing side — operators can grep for the missing phase and decide.
aggregate_duration_delta_pct: Option<f64>Aggregate wall-clock delta. Positive ⇒ slower in current.
aggregate_throughput_delta_pct: Option<f64>Aggregate items/sec delta. Positive ⇒ faster in current.
dominant_phase_shift: Option<(RefreshPhase, RefreshPhase)>Some((from, to)) when the dominant phase shifted between
baseline and current. A dominant-phase shift is itself a
regression signal — the operator should look at why the
hot phase changed even if absolute totals are similar.
Implementations§
Source§impl RefreshLedgerEvidenceComparison
impl RefreshLedgerEvidenceComparison
Sourcepub fn regression_verdict(
&self,
thresholds: &RegressionVerdictThresholds,
) -> RegressionVerdict
pub fn regression_verdict( &self, thresholds: &RegressionVerdictThresholds, ) -> RegressionVerdict
Compute the CI hard-gate verdict for this comparison against
caller-supplied thresholds. Pure function; no I/O. Use
emit_tracing_summary for operator-visibility soft signaling
instead of CI gating.
coding_agent_session_search-ibuuh.24: this is the
bench-CI consumer of compare_to. A regression test asserts
the verdict tiering matches the threshold contract exactly,
so a project tuning thresholds for its own bench harness
gets predictable behavior at the boundary cases.
Degenerate cases:
aggregate_duration_delta_pct == None(baseline missing or empty) ⇒Clean— no measurement to gate on.- Negative duration delta (improvement) ⇒ always
Clean, regardless of threshold polarity (an improvement cannot trigger a regression failure).
Source§impl RefreshLedgerEvidenceComparison
impl RefreshLedgerEvidenceComparison
Sourcepub fn emit_tracing_summary(&self)
pub fn emit_tracing_summary(&self)
Emit a single structured tracing event summarizing the cross-run comparison. Operators see “this rebuild was N% slower than the previous publish” in default-level logs without running a benchmark harness.
coding_agent_session_search-ibuuh.24: pure helper that any
caller (the publish path, a cass status summary surface,
CI bench gates) can invoke after compare_to. Severity is
chosen by the regression magnitude:
aggregate_duration_delta_pct >= +25.0⇒warn(significant slowdown — surface in default logs so the operator sees it without dredging)aggregate_duration_delta_pct <= -10.0⇒info(notable improvement — worth surfacing as a positive signal)- otherwise ⇒
debug(steady state — high-volume noise on every publish; only visible at debug level)
The thresholds (+25% slowdown / -10% improvement) are the “operator should look” signal levels, NOT a hard regression gate. CI hard gates compare against benchmark baselines with project-specific thresholds; this helper is for ambient operator visibility.
dominant_phase_shift is reported on every emission
regardless of severity tier — a hot-phase change is itself
a regression signal worth surfacing even when the absolute
totals look similar.
Trait Implementations§
Source§impl Clone for RefreshLedgerEvidenceComparison
impl Clone for RefreshLedgerEvidenceComparison
Source§fn clone(&self) -> RefreshLedgerEvidenceComparison
fn clone(&self) -> RefreshLedgerEvidenceComparison
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<'de> Deserialize<'de> for RefreshLedgerEvidenceComparison
impl<'de> Deserialize<'de> for RefreshLedgerEvidenceComparison
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl PartialEq for RefreshLedgerEvidenceComparison
impl PartialEq for RefreshLedgerEvidenceComparison
Source§fn eq(&self, other: &RefreshLedgerEvidenceComparison) -> bool
fn eq(&self, other: &RefreshLedgerEvidenceComparison) -> bool
self and other values to be equal, and is used by ==.impl StructuralPartialEq for RefreshLedgerEvidenceComparison
Auto Trait Implementations§
impl Freeze for RefreshLedgerEvidenceComparison
impl RefUnwindSafe for RefreshLedgerEvidenceComparison
impl Send for RefreshLedgerEvidenceComparison
impl Sync for RefreshLedgerEvidenceComparison
impl Unpin for RefreshLedgerEvidenceComparison
impl UnsafeUnpin for RefreshLedgerEvidenceComparison
impl UnwindSafe for RefreshLedgerEvidenceComparison
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, _span: NoopSpan) -> Self
fn instrument(self, _span: NoopSpan) -> Self
Source§fn in_current_span(self) -> Self
fn in_current_span(self) -> Self
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more