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
45
46
47
48
49
50
51
52
53
54
55
//! Extraction reliability scoring
//!
//! Computes a 0.0–1.0 reliability score for [`ExtractionResult`] outputs so
//! fallback chains can optimize for *data quality*, not only fetch success.
//!
//! # Score components
//!
//! The score is the weighted sum of three sub-scores, clamped to `[0.0, 1.0]`:
//!
//! | Sub-score | Default weight | Source |
//! |------------------------|---------------:|--------------------------------------------------|
//! | `schema_completeness` | 0.70 | `successful_regions / total_regions` |
//! | `transformation_success`| 0.30 | `1 − transformation_failure_rate` |
//! | `retry_penalty` | 0.10 | `retry_count / max_retries` (clamped) |
//!
//! `retry_penalty` is **subtracted** from the weighted sum — it represents a
//! quality discount for results that took many retries to produce.
//!
//! # Interpretation bands
//!
//! The continuous `overall` score is bucketed into three discrete bands so
//! callers can branch on a single [`ReliabilityBand`] value:
//!
//! | Band | Score range | Interpretation |
//! |---------|---------------|-------------------------------------------------|
//! | `High` | `0.85..=1.00` | Production-ready; trust the result. |
//! | `Medium`| `0.50..0.85` | Partial; treat as best-effort, retry if needed. |
//! | `Low` | `0.00..0.50` | Unreliable; prefer an alternative fallback. |
//!
//! # Selection policy
//!
//! The [`ScoreWeightedSelector`] helper ranks a list of `(name, score)`
//! candidates and picks the highest-scoring one. Callers can apply a custom
//! [`ScoringWeights`] to tune the importance of each sub-score for their
//! target class.
//!
//! # Example
//!
//! ```
//! use stygian_plugin::domain::{ExtractionResult, IdempotencyKey};
//! use stygian_plugin::reliability::{ReliabilityScorer, ReliabilityBand};
//!
//! let result = ExtractionResult::new(IdempotencyKey::new());
//! let score = ReliabilityScorer::new().score_extraction(&result, 0);
//! assert_eq!(score.band, ReliabilityBand::High); // empty template -> vacuously complete
//! assert!((score.overall - 1.0).abs() < f32::EPSILON);
//! ```
pub use ;
pub use ;
pub use ;