pub enum Outcome {
Pass {
leak_probability: f64,
effect: EffectEstimate,
samples_used: usize,
quality: MeasurementQuality,
diagnostics: Diagnostics,
theta_user: f64,
theta_eff: f64,
theta_floor: f64,
},
Fail {
leak_probability: f64,
effect: EffectEstimate,
exploitability: Exploitability,
samples_used: usize,
quality: MeasurementQuality,
diagnostics: Diagnostics,
theta_user: f64,
theta_eff: f64,
theta_floor: f64,
},
Inconclusive {
reason: InconclusiveReason,
leak_probability: f64,
effect: EffectEstimate,
samples_used: usize,
quality: MeasurementQuality,
diagnostics: Diagnostics,
theta_user: f64,
theta_eff: f64,
theta_floor: f64,
},
Unmeasurable {
operation_ns: f64,
threshold_ns: f64,
platform: String,
recommendation: String,
},
Research(ResearchOutcome),
}Expand description
Top-level outcome of a timing test.
The adaptive Bayesian oracle returns one of four outcomes:
Pass: No timing leak detected (leak_probability < pass_threshold)Fail: Timing leak confirmed (leak_probability > fail_threshold)Inconclusive: Cannot reach a definitive conclusionUnmeasurable: Operation too fast to measure on this platform
See spec Section 4.1 (Result Types).
Variants§
Pass
No timing leak detected.
The posterior probability of a timing leak is below the pass threshold (default 0.05), meaning we’re confident there is no exploitable leak.
Fields
leak_probability: f64Posterior probability of timing leak: P(effect > theta | data). Will be < pass_threshold (default 0.05).
effect: EffectEstimateEffect size estimate (shift and tail components).
quality: MeasurementQualityMeasurement quality assessment.
diagnostics: DiagnosticsDiagnostic information for debugging.
Fail
Timing leak confirmed.
The posterior probability of a timing leak exceeds the fail threshold (default 0.95), meaning we’re confident there is an exploitable leak.
Fields
leak_probability: f64Posterior probability of timing leak: P(effect > theta | data). Will be > fail_threshold (default 0.95).
effect: EffectEstimateEffect size estimate (shift and tail components).
exploitability: ExploitabilityExploitability assessment based on effect magnitude.
quality: MeasurementQualityMeasurement quality assessment.
diagnostics: DiagnosticsDiagnostic information for debugging.
Inconclusive
Cannot reach a definitive conclusion.
The posterior probability is between pass_threshold and fail_threshold, or the analysis hit a limit (timeout, sample budget, noise).
Fields
reason: InconclusiveReasonReason why the result is inconclusive.
effect: EffectEstimateEffect size estimate (may have wide credible intervals).
quality: MeasurementQualityMeasurement quality assessment.
diagnostics: DiagnosticsDiagnostic information for debugging.
Unmeasurable
Operation too fast to measure reliably on this platform.
The operation completes faster than the timer’s resolution allows for meaningful measurement, even with adaptive batching.
Fields
Research(ResearchOutcome)
Research mode result.
Returned when using AttackerModel::Research. Unlike Pass/Fail/Inconclusive
which make threshold-based decisions, research mode characterizes the
timing behavior relative to the measurement floor using CI-based semantics.
See ResearchOutcome for details on the stopping conditions.
Implementations§
Source§impl Outcome
impl Outcome
Sourcepub fn is_conclusive(&self) -> bool
pub fn is_conclusive(&self) -> bool
Check if the result is conclusive (either Pass or Fail).
Sourcepub fn is_measurable(&self) -> bool
pub fn is_measurable(&self) -> bool
Check if the operation was measurable.
Sourcepub fn leak_probability(&self) -> Option<f64>
pub fn leak_probability(&self) -> Option<f64>
Get the leak probability if available.
Returns None for Unmeasurable and Research (research mode uses CI, not probability).
Sourcepub fn effect(&self) -> Option<&EffectEstimate>
pub fn effect(&self) -> Option<&EffectEstimate>
Get the effect estimate if available.
Sourcepub fn quality(&self) -> Option<MeasurementQuality>
pub fn quality(&self) -> Option<MeasurementQuality>
Get the measurement quality if available.
Sourcepub fn diagnostics(&self) -> Option<&Diagnostics>
pub fn diagnostics(&self) -> Option<&Diagnostics>
Get the diagnostics if available.
Sourcepub fn samples_used(&self) -> Option<usize>
pub fn samples_used(&self) -> Option<usize>
Get the number of samples used if available.
Sourcepub fn is_reliable(&self) -> bool
pub fn is_reliable(&self) -> bool
Check if the measurement is reliable enough for assertions.
Returns true if:
- Test is conclusive (Pass or Fail), AND
- Quality is not TooNoisy, OR posterior is very conclusive (< 0.1 or > 0.9)
The key insight: a very conclusive posterior is trustworthy even with noisy measurements - the signal overcame the noise.
For Research mode, reliability is based on whether the CI is clearly above or below the measurement floor.
Sourcepub fn unwrap_pass(
self,
) -> (f64, EffectEstimate, MeasurementQuality, Diagnostics)
pub fn unwrap_pass( self, ) -> (f64, EffectEstimate, MeasurementQuality, Diagnostics)
Unwrap a Pass result, panicking otherwise.
Sourcepub fn unwrap_fail(
self,
) -> (f64, EffectEstimate, Exploitability, MeasurementQuality, Diagnostics)
pub fn unwrap_fail( self, ) -> (f64, EffectEstimate, Exploitability, MeasurementQuality, Diagnostics)
Unwrap a Fail result, panicking otherwise.
Sourcepub fn handle_unreliable(
self,
test_name: &str,
policy: UnreliablePolicy,
) -> Option<Self>
pub fn handle_unreliable( self, test_name: &str, policy: UnreliablePolicy, ) -> Option<Self>
Handle unreliable results according to policy.
Returns Some(self) if the result is reliable.
For unreliable results:
FailOpen: prints warning, returnsNoneFailClosed: panics
§Example
let outcome = oracle.test(...);
if let Some(result) = outcome.handle_unreliable("test_name", UnreliablePolicy::FailOpen) {
assert!(result.passed());
}Trait Implementations§
Source§impl<'de> Deserialize<'de> for Outcome
impl<'de> Deserialize<'de> for Outcome
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>,
Auto Trait Implementations§
impl Freeze for Outcome
impl RefUnwindSafe for Outcome
impl Send for Outcome
impl Sync for Outcome
impl Unpin for Outcome
impl UnwindSafe for Outcome
Blanket Implementations§
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<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.