4949// ─────────────────────────────────────────────────────────────────────────────
5050
5151/// SSIM / PSNR pair for a parity gate.
52+ ///
53+ /// # Examples
54+ ///
55+ /// ```
56+ /// use cesium::fixtures::Thresholds;
57+ ///
58+ /// let t = Thresholds::SYNTHETIC_TIGHT;
59+ /// assert_eq!(t.min_ssim, 0.99);
60+ /// assert_eq!(t.min_psnr_db, 40.0);
61+ ///
62+ /// // Thresholds are ordered: SMOKE < INRIA < SYNTHETIC
63+ /// assert!(Thresholds::SMOKE_TEST.min_ssim < Thresholds::INRIA_PLY_NOMINAL.min_ssim);
64+ /// assert!(Thresholds::INRIA_PLY_NOMINAL.min_ssim < Thresholds::SYNTHETIC_TIGHT.min_ssim);
65+ /// ```
5266#[ derive( Debug , Clone , Copy , PartialEq ) ]
5367pub struct Thresholds {
5468 /// Minimum acceptable SSIM in `[0, 1]`.
@@ -88,6 +102,18 @@ impl Thresholds {
88102/// A `Fixture` names a scene and records its provenance. It does NOT hold the
89103/// actual scene data (too large for in-memory constants); the oracle pipeline
90104/// loads data from disk at test time.
105+ ///
106+ /// # Examples
107+ ///
108+ /// ```
109+ /// use cesium::fixtures::scenes;
110+ ///
111+ /// let f = scenes::SYNTHETIC_UNIT.clone();
112+ /// assert_eq!(f.id, "synthetic_unit");
113+ /// assert_eq!(f.expected_gaussian_count, Some(4));
114+ /// assert_eq!(f.width, 64);
115+ /// assert_eq!(f.height, 64);
116+ /// ```
91117#[ derive( Debug , Clone ) ]
92118pub struct Fixture {
93119 /// Short identifier used in test output (e.g. `"settlement_dev"`).
@@ -161,6 +187,16 @@ pub mod scenes {
161187/// Use [`ParityGate::check`] to evaluate a [`crate::oracle::ParityMetrics`]
162188/// against the gate. The gate reports pass/fail but does not panic — the
163189/// caller decides whether a failed gate is a CI hard failure.
190+ ///
191+ /// # Examples
192+ ///
193+ /// ```
194+ /// use cesium::fixtures::gates;
195+ ///
196+ /// let gate = gates::synthetic_unit_tight();
197+ /// assert_eq!(gate.fixture.id, "synthetic_unit");
198+ /// assert_eq!(gate.thresholds.min_ssim, 0.99);
199+ /// ```
164200#[ derive( Debug , Clone ) ]
165201pub struct ParityGate {
166202 /// The scene this gate applies to.
@@ -170,6 +206,21 @@ pub struct ParityGate {
170206}
171207
172208/// Result of evaluating a parity gate.
209+ ///
210+ /// # Examples
211+ ///
212+ /// ```
213+ /// use cesium::fixtures::{gates, GateResult};
214+ /// use cesium::oracle::ParityMetrics;
215+ ///
216+ /// let fb: Vec<f32> = vec![0.5, 0.3, 0.8, 0.1, 0.9, 0.2];
217+ /// let metrics = ParityMetrics::compute(&fb, &fb).unwrap();
218+ /// let gate = gates::settlement_dev_smoke();
219+ /// let result: GateResult = gate.check(&metrics);
220+ /// assert!(result.passed);
221+ /// assert!(result.ssim_margin >= 0.0);
222+ /// assert!(result.psnr_margin_db.is_infinite());
223+ /// ```
173224#[ derive( Debug , Clone , PartialEq ) ]
174225pub struct GateResult {
175226 /// Whether the gate passed.
@@ -186,6 +237,28 @@ pub struct GateResult {
186237
187238impl ParityGate {
188239 /// Evaluate the gate against observed metrics.
240+ ///
241+ /// Returns a [`GateResult`] with `passed = true` when both `ssim` and
242+ /// `psnr` meet the gate's [`Thresholds`]. Identical buffers produce
243+ /// SSIM = 1.0 and infinite PSNR, which always passes.
244+ ///
245+ /// # Examples
246+ ///
247+ /// ```
248+ /// use cesium::fixtures::gates;
249+ /// use cesium::oracle::ParityMetrics;
250+ ///
251+ /// // Two identical small framebuffers (3 pixels × RGB = 9 samples).
252+ /// let fb: Vec<f32> = vec![0.2, 0.5, 0.8, 0.1, 0.4, 0.9, 0.3, 0.6, 0.7];
253+ /// let metrics = ParityMetrics::compute(&fb, &fb).unwrap();
254+ ///
255+ /// // Identical buffers → SSIM 1.0, infinite PSNR → passes even the tight gate.
256+ /// let gate = cesium::fixtures::gates::synthetic_unit_tight();
257+ /// let result = gate.check(&metrics);
258+ /// assert!(result.passed);
259+ /// assert_eq!(result.ssim, 1.0);
260+ /// assert!(result.psnr.is_infinite());
261+ /// ```
189262 pub fn check ( & self , metrics : & crate :: oracle:: ParityMetrics ) -> GateResult {
190263 let ssim_margin = metrics. ssim - self . thresholds . min_ssim ;
191264 let psnr_margin_db = if metrics. psnr . is_infinite ( ) {
@@ -209,6 +282,19 @@ pub mod gates {
209282 use super :: { scenes, ParityGate , Thresholds } ;
210283
211284 /// Smoke test gate for the settlement_dev scene.
285+ ///
286+ /// Uses [`Thresholds::SMOKE_TEST`] (SSIM ≥ 0.80, PSNR ≥ 20 dB).
287+ ///
288+ /// # Examples
289+ ///
290+ /// ```
291+ /// use cesium::fixtures::gates;
292+ ///
293+ /// let gate = gates::settlement_dev_smoke();
294+ /// assert_eq!(gate.fixture.id, "settlement_dev");
295+ /// assert_eq!(gate.thresholds.min_ssim, 0.80);
296+ /// assert_eq!(gate.thresholds.min_psnr_db, 20.0);
297+ /// ```
212298 pub fn settlement_dev_smoke ( ) -> ParityGate {
213299 ParityGate {
214300 fixture : scenes:: SETTLEMENT_DEV . clone ( ) ,
@@ -217,6 +303,19 @@ pub mod gates {
217303 }
218304
219305 /// Nominal gate for the settlement_dev scene (accounts for sort-order risk).
306+ ///
307+ /// Uses [`Thresholds::INRIA_PLY_NOMINAL`] (SSIM ≥ 0.95, PSNR ≥ 30 dB).
308+ ///
309+ /// # Examples
310+ ///
311+ /// ```
312+ /// use cesium::fixtures::gates;
313+ ///
314+ /// let gate = gates::settlement_dev_nominal();
315+ /// assert_eq!(gate.fixture.id, "settlement_dev");
316+ /// assert_eq!(gate.thresholds.min_ssim, 0.95);
317+ /// assert_eq!(gate.thresholds.min_psnr_db, 30.0);
318+ /// ```
220319 pub fn settlement_dev_nominal ( ) -> ParityGate {
221320 ParityGate {
222321 fixture : scenes:: SETTLEMENT_DEV . clone ( ) ,
@@ -225,6 +324,27 @@ pub mod gates {
225324 }
226325
227326 /// Tight gate for the synthetic unit scene.
327+ ///
328+ /// Uses [`Thresholds::SYNTHETIC_TIGHT`] (SSIM ≥ 0.99, PSNR ≥ 40 dB).
329+ ///
330+ /// # Examples
331+ ///
332+ /// ```
333+ /// use cesium::fixtures::gates;
334+ /// use cesium::oracle::ParityMetrics;
335+ ///
336+ /// // Identical framebuffers → SSIM 1.0, infinite PSNR → passes the tight gate.
337+ /// let fb: Vec<f32> = vec![0.2, 0.5, 0.8, 0.1, 0.4, 0.9, 0.3, 0.6, 0.7];
338+ /// let metrics = ParityMetrics::compute(&fb, &fb).unwrap();
339+ ///
340+ /// let gate = gates::synthetic_unit_tight();
341+ /// assert_eq!(gate.fixture.id, "synthetic_unit");
342+ /// assert_eq!(gate.thresholds.min_ssim, 0.99);
343+ /// assert_eq!(gate.thresholds.min_psnr_db, 40.0);
344+ ///
345+ /// let result = gate.check(&metrics);
346+ /// assert!(result.passed);
347+ /// ```
228348 pub fn synthetic_unit_tight ( ) -> ParityGate {
229349 ParityGate {
230350 fixture : scenes:: SYNTHETIC_UNIT . clone ( ) ,
0 commit comments