Skip to main content

omena_cascade/
statistics.rs

1//! Spin-glass-inspired cascade statistics and advisory theorem surfaces.
2//!
3//! These records are intentionally conservative: deterministic contracts remain
4//! separate from advisory Monte Carlo and ultrametric observation surfaces.
5
6use serde::Serialize;
7
8#[derive(Debug, Clone, PartialEq, Serialize)]
9#[serde(rename_all = "camelCase")]
10pub struct CascadeSpinGlassSummaryV0 {
11    pub schema_version: &'static str,
12    pub product: &'static str,
13    pub layer_marker: &'static str,
14    pub feature_gate: &'static str,
15    pub hamiltonian: CascadeSpinGlassHamiltonianV0,
16    pub frustration: CascadeFrustrationV0,
17    pub replica_overlap: CascadeReplicaOverlapV0,
18    pub stability_score: CascadeStabilityScoreV0,
19    pub ultrametric_corpus: CascadeSpinGlassUltrametricCorpusV0,
20    pub theorem_contracts: Vec<CascadeSpinGlassTheoremV0>,
21    pub advisory_policy: SpinGlassMonteCarloPolicyV0,
22}
23
24#[derive(Debug, Clone, PartialEq, Serialize)]
25#[serde(rename_all = "camelCase")]
26pub struct CascadeSpinGlassHamiltonianV0 {
27    pub schema_version: &'static str,
28    pub product: &'static str,
29    pub layer_marker: &'static str,
30    pub feature_gate: &'static str,
31    pub unit: &'static str,
32    pub energy_bits: f64,
33    pub deterministic: bool,
34}
35
36#[derive(Debug, Clone, PartialEq, Serialize)]
37#[serde(rename_all = "camelCase")]
38pub struct CascadeFrustrationV0 {
39    pub schema_version: &'static str,
40    pub product: &'static str,
41    pub layer_marker: &'static str,
42    pub feature_gate: &'static str,
43    pub frustrated_edge_count: usize,
44    pub total_edge_count: usize,
45    pub advisory_only: bool,
46}
47
48#[derive(Debug, Clone, PartialEq, Serialize)]
49#[serde(rename_all = "camelCase")]
50pub struct CascadeReplicaOverlapV0 {
51    pub schema_version: &'static str,
52    pub product: &'static str,
53    pub layer_marker: &'static str,
54    pub feature_gate: &'static str,
55    pub overlap_bucket_count: usize,
56    pub parisi_breakpoint_m: Option<f64>,
57    pub advisory_only: bool,
58}
59
60#[derive(Debug, Clone, PartialEq, Serialize)]
61#[serde(rename_all = "camelCase")]
62pub struct CascadeStabilityScoreV0 {
63    pub schema_version: &'static str,
64    pub product: &'static str,
65    pub layer_marker: &'static str,
66    pub feature_gate: &'static str,
67    pub score: f64,
68    pub deterministic_component_passed: bool,
69    pub advisory_only: bool,
70}
71
72#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
73#[serde(rename_all = "camelCase")]
74pub struct CascadeUltrametricPathV0 {
75    pub origin: u8,
76    pub layer: u8,
77    pub scope: u8,
78    pub rule: u8,
79    pub declaration: u8,
80}
81
82#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
83#[serde(rename_all = "camelCase")]
84pub struct CascadeSpinGlassUltrametricCorpusV0 {
85    pub schema_version: &'static str,
86    pub product: &'static str,
87    pub layer_marker: &'static str,
88    pub feature_gate: &'static str,
89    pub path_count: usize,
90    pub triple_count: usize,
91    pub max_distance: u8,
92    pub exhaustive_binary_five_tier_domain: bool,
93    pub strong_triangle_passed: bool,
94}
95
96#[derive(Debug, Clone, PartialEq, Serialize)]
97#[serde(rename_all = "camelCase")]
98pub struct CascadeSpinGlassTheoremV0 {
99    pub schema_version: &'static str,
100    pub product: &'static str,
101    pub layer_marker: &'static str,
102    pub feature_gate: &'static str,
103    pub theorem_id: &'static str,
104    pub statement: &'static str,
105    pub deterministic: bool,
106    pub passed: bool,
107}
108
109#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
110#[serde(rename_all = "camelCase")]
111pub struct SpinGlassMonteCarloPolicyV0 {
112    pub schema_version: &'static str,
113    pub product: &'static str,
114    pub layer_marker: &'static str,
115    pub feature_gate: &'static str,
116    pub advisory_only: bool,
117    pub bucket_count: usize,
118    pub buckets: Vec<SpinGlassMonteCarloBucketV0>,
119    pub task_budget_ms: u64,
120    pub debounce_ms: u64,
121}
122
123#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
124#[serde(rename_all = "camelCase")]
125pub struct SpinGlassMonteCarloBucketV0 {
126    pub schema_version: &'static str,
127    pub product: &'static str,
128    pub layer_marker: &'static str,
129    pub feature_gate: &'static str,
130    pub bucket: &'static str,
131    pub max_variable_count: usize,
132    pub sample_count: usize,
133}
134
135pub fn summarize_cascade_spin_glass_statistics() -> CascadeSpinGlassSummaryV0 {
136    let ultrametric_corpus = verify_spin_glass_ultrametric_corpus_v0();
137
138    CascadeSpinGlassSummaryV0 {
139        schema_version: "0",
140        product: "omena-cascade.spin-glass",
141        layer_marker: "statistical-mechanics",
142        feature_gate: "spin-glass",
143        hamiltonian: summarize_spin_glass_hamiltonian(&[1, 2, 3, 5]),
144        frustration: summarize_cascade_frustration(0, 3),
145        replica_overlap: summarize_replica_overlap(4, Some(0.5)),
146        stability_score: summarize_cascade_stability_score(1.0),
147        ultrametric_corpus: ultrametric_corpus.clone(),
148        theorem_contracts: vec![
149            CascadeSpinGlassTheoremV0 {
150                schema_version: "0",
151                product: "omena-cascade.spin-glass-theorem",
152                layer_marker: "statistical-mechanics",
153                feature_gate: "spin-glass",
154                theorem_id: "D1",
155                statement: "5-tier cascade ultrametric strong triangle corpus passes",
156                deterministic: true,
157                passed: ultrametric_corpus.strong_triangle_passed,
158            },
159            CascadeSpinGlassTheoremV0 {
160                schema_version: "0",
161                product: "omena-cascade.spin-glass-theorem",
162                layer_marker: "statistical-mechanics",
163                feature_gate: "spin-glass",
164                theorem_id: "D3",
165                statement: "tropical Hamiltonian monotonicity fixture passes",
166                deterministic: true,
167                passed: prove_tropical_hamiltonian_monotone(&[1, 2, 3, 5]),
168            },
169            CascadeSpinGlassTheoremV0 {
170                schema_version: "0",
171                product: "omena-cascade.spin-glass-theorem",
172                layer_marker: "statistical-mechanics",
173                feature_gate: "spin-glass",
174                theorem_id: "D4",
175                statement: "ultrametric isomorphism fixture passes",
176                deterministic: true,
177                passed: prove_ultrametric_isomorphism(&[0, 2, 2]),
178            },
179        ],
180        advisory_policy: spin_glass_monte_carlo_policy(),
181    }
182}
183
184pub fn summarize_spin_glass_hamiltonian(energies: &[u32]) -> CascadeSpinGlassHamiltonianV0 {
185    CascadeSpinGlassHamiltonianV0 {
186        schema_version: "0",
187        product: "omena-cascade.spin-glass-hamiltonian",
188        layer_marker: "statistical-mechanics",
189        feature_gate: "spin-glass",
190        unit: "bit",
191        energy_bits: energies.iter().map(|value| f64::from(*value)).sum(),
192        deterministic: true,
193    }
194}
195
196pub fn summarize_cascade_frustration(
197    frustrated_edge_count: usize,
198    total_edge_count: usize,
199) -> CascadeFrustrationV0 {
200    CascadeFrustrationV0 {
201        schema_version: "0",
202        product: "omena-cascade.frustration",
203        layer_marker: "statistical-mechanics",
204        feature_gate: "spin-glass",
205        frustrated_edge_count,
206        total_edge_count,
207        advisory_only: true,
208    }
209}
210
211pub fn summarize_replica_overlap(
212    overlap_bucket_count: usize,
213    parisi_breakpoint_m: Option<f64>,
214) -> CascadeReplicaOverlapV0 {
215    CascadeReplicaOverlapV0 {
216        schema_version: "0",
217        product: "omena-cascade.replica-overlap",
218        layer_marker: "statistical-mechanics",
219        feature_gate: "spin-glass",
220        overlap_bucket_count,
221        parisi_breakpoint_m,
222        advisory_only: true,
223    }
224}
225
226pub fn summarize_cascade_stability_score(score: f64) -> CascadeStabilityScoreV0 {
227    CascadeStabilityScoreV0 {
228        schema_version: "0",
229        product: "omena-cascade.stability-score",
230        layer_marker: "statistical-mechanics",
231        feature_gate: "spin-glass",
232        score,
233        deterministic_component_passed: verify_spin_glass_ultrametric_corpus_v0()
234            .strong_triangle_passed
235            && prove_tropical_hamiltonian_monotone(&[1, 2, 3, 5])
236            && prove_ultrametric_isomorphism(&[0, 2, 2]),
237        advisory_only: true,
238    }
239}
240
241pub fn spin_glass_monte_carlo_policy() -> SpinGlassMonteCarloPolicyV0 {
242    SpinGlassMonteCarloPolicyV0 {
243        schema_version: "0",
244        product: "omena-cascade.spin-glass-monte-carlo-policy",
245        layer_marker: "statistical-mechanics",
246        feature_gate: "spin-glass",
247        advisory_only: true,
248        bucket_count: 4,
249        buckets: vec![
250            SpinGlassMonteCarloBucketV0 {
251                schema_version: "0",
252                product: "omena-cascade.spin-glass-monte-carlo-bucket",
253                layer_marker: "statistical-mechanics",
254                feature_gate: "spin-glass",
255                bucket: "tiny",
256                max_variable_count: 16,
257                sample_count: 0,
258            },
259            SpinGlassMonteCarloBucketV0 {
260                schema_version: "0",
261                product: "omena-cascade.spin-glass-monte-carlo-bucket",
262                layer_marker: "statistical-mechanics",
263                feature_gate: "spin-glass",
264                bucket: "small",
265                max_variable_count: 64,
266                sample_count: 128,
267            },
268            SpinGlassMonteCarloBucketV0 {
269                schema_version: "0",
270                product: "omena-cascade.spin-glass-monte-carlo-bucket",
271                layer_marker: "statistical-mechanics",
272                feature_gate: "spin-glass",
273                bucket: "medium",
274                max_variable_count: 256,
275                sample_count: 512,
276            },
277            SpinGlassMonteCarloBucketV0 {
278                schema_version: "0",
279                product: "omena-cascade.spin-glass-monte-carlo-bucket",
280                layer_marker: "statistical-mechanics",
281                feature_gate: "spin-glass",
282                bucket: "large",
283                max_variable_count: usize::MAX,
284                sample_count: 1024,
285            },
286        ],
287        task_budget_ms: 200,
288        debounce_ms: 500,
289    }
290}
291
292pub fn spin_glass_ultrametric_binary_five_tier_corpus_v0() -> Vec<CascadeUltrametricPathV0> {
293    let mut paths = Vec::with_capacity(32);
294
295    for origin in 0..=1 {
296        for layer in 0..=1 {
297            for scope in 0..=1 {
298                for rule in 0..=1 {
299                    for declaration in 0..=1 {
300                        paths.push(CascadeUltrametricPathV0 {
301                            origin,
302                            layer,
303                            scope,
304                            rule,
305                            declaration,
306                        });
307                    }
308                }
309            }
310        }
311    }
312
313    paths
314}
315
316pub fn cascade_ultrametric_distance_v0(
317    lhs: CascadeUltrametricPathV0,
318    rhs: CascadeUltrametricPathV0,
319) -> u8 {
320    if lhs.origin != rhs.origin {
321        5
322    } else if lhs.layer != rhs.layer {
323        4
324    } else if lhs.scope != rhs.scope {
325        3
326    } else if lhs.rule != rhs.rule {
327        2
328    } else if lhs.declaration != rhs.declaration {
329        1
330    } else {
331        0
332    }
333}
334
335pub fn prove_cascade_ultrametric_strong_triangle_v0(
336    lhs: CascadeUltrametricPathV0,
337    mid: CascadeUltrametricPathV0,
338    rhs: CascadeUltrametricPathV0,
339) -> bool {
340    let direct = cascade_ultrametric_distance_v0(lhs, rhs);
341    let via_lhs_mid = cascade_ultrametric_distance_v0(lhs, mid);
342    let via_mid_rhs = cascade_ultrametric_distance_v0(mid, rhs);
343
344    direct <= via_lhs_mid.max(via_mid_rhs)
345}
346
347pub fn verify_spin_glass_ultrametric_corpus_v0() -> CascadeSpinGlassUltrametricCorpusV0 {
348    let paths = spin_glass_ultrametric_binary_five_tier_corpus_v0();
349    let mut max_distance = 0;
350    let mut triple_count = 0;
351    let mut strong_triangle_passed = true;
352
353    for lhs in &paths {
354        for rhs in &paths {
355            max_distance = max_distance.max(cascade_ultrametric_distance_v0(*lhs, *rhs));
356        }
357    }
358
359    for lhs in &paths {
360        for mid in &paths {
361            for rhs in &paths {
362                triple_count += 1;
363                strong_triangle_passed &=
364                    prove_cascade_ultrametric_strong_triangle_v0(*lhs, *mid, *rhs);
365            }
366        }
367    }
368
369    CascadeSpinGlassUltrametricCorpusV0 {
370        schema_version: "0",
371        product: "omena-cascade.spin-glass-ultrametric-corpus",
372        layer_marker: "statistical-mechanics",
373        feature_gate: "spin-glass",
374        path_count: paths.len(),
375        triple_count,
376        max_distance,
377        exhaustive_binary_five_tier_domain: paths.len() == 32,
378        strong_triangle_passed,
379    }
380}
381
382pub fn prove_strong_triangle_inequality(a: u32, b: u32, c: u32) -> bool {
383    let lhs = a.max(c);
384    let rhs = a.max(b).max(b.max(c));
385    lhs <= rhs
386}
387
388pub fn prove_tropical_hamiltonian_monotone(energies: &[u32]) -> bool {
389    energies.windows(2).all(|pair| pair[0] <= pair[1])
390}
391
392pub fn prove_ultrametric_isomorphism(distances_from_root: &[u32]) -> bool {
393    distances_from_root
394        .windows(2)
395        .all(|pair| pair[0] == 0 || pair[0] == pair[1])
396}
397
398#[cfg(test)]
399mod tests {
400    use super::*;
401
402    #[test]
403    fn deterministic_spin_glass_theorems_pass() {
404        let summary = summarize_cascade_spin_glass_statistics();
405
406        assert_eq!(summary.schema_version, "0");
407        assert_eq!(summary.layer_marker, "statistical-mechanics");
408        assert_eq!(summary.feature_gate, "spin-glass");
409        assert_eq!(summary.hamiltonian.schema_version, "0");
410        assert_eq!(summary.hamiltonian.feature_gate, "spin-glass");
411        assert_eq!(summary.hamiltonian.unit, "bit");
412        assert_eq!(summary.frustration.schema_version, "0");
413        assert_eq!(summary.frustration.feature_gate, "spin-glass");
414        assert_eq!(summary.replica_overlap.schema_version, "0");
415        assert_eq!(summary.replica_overlap.feature_gate, "spin-glass");
416        assert_eq!(summary.stability_score.schema_version, "0");
417        assert_eq!(summary.stability_score.feature_gate, "spin-glass");
418        assert!(summary.stability_score.deterministic_component_passed);
419        assert_eq!(summary.ultrametric_corpus.schema_version, "0");
420        assert_eq!(summary.ultrametric_corpus.path_count, 32);
421        assert_eq!(summary.ultrametric_corpus.triple_count, 32 * 32 * 32);
422        assert_eq!(summary.ultrametric_corpus.max_distance, 5);
423        assert!(summary.ultrametric_corpus.strong_triangle_passed);
424        assert!(
425            summary
426                .theorem_contracts
427                .iter()
428                .all(|theorem| theorem.schema_version == "0"
429                    && theorem.feature_gate == "spin-glass"
430                    && theorem.passed)
431        );
432        assert!(summary.advisory_policy.advisory_only);
433        assert_eq!(summary.advisory_policy.bucket_count, 4);
434    }
435
436    #[test]
437    fn spin_glass_monte_carlo_policy_enforces_m4_alpha_runtime_bounds() {
438        let policy = spin_glass_monte_carlo_policy();
439
440        assert_eq!(policy.schema_version, "0");
441        assert_eq!(
442            policy.product,
443            "omena-cascade.spin-glass-monte-carlo-policy"
444        );
445        assert_eq!(policy.layer_marker, "statistical-mechanics");
446        assert_eq!(policy.feature_gate, "spin-glass");
447        assert!(policy.advisory_only);
448        assert_eq!(policy.bucket_count, 4);
449        assert_eq!(policy.task_budget_ms, 200);
450        assert_eq!(policy.debounce_ms, 500);
451        assert_eq!(policy.buckets.len(), policy.bucket_count);
452        assert_eq!(policy.buckets[0].bucket, "tiny");
453        assert_eq!(policy.buckets[0].max_variable_count, 16);
454        assert_eq!(policy.buckets[0].sample_count, 0);
455        assert_eq!(policy.buckets[1].bucket, "small");
456        assert_eq!(policy.buckets[1].max_variable_count, 64);
457        assert_eq!(policy.buckets[1].sample_count, 128);
458        assert_eq!(policy.buckets[2].bucket, "medium");
459        assert_eq!(policy.buckets[2].max_variable_count, 256);
460        assert_eq!(policy.buckets[2].sample_count, 512);
461        assert_eq!(policy.buckets[3].bucket, "large");
462        assert_eq!(policy.buckets[3].max_variable_count, usize::MAX);
463        assert_eq!(policy.buckets[3].sample_count, 1024);
464    }
465
466    #[test]
467    fn frustration_measure_contract_is_advisory() {
468        let frustration = summarize_cascade_frustration(1, 4);
469
470        assert_eq!(frustration.schema_version, "0");
471        assert_eq!(frustration.layer_marker, "statistical-mechanics");
472        assert!(frustration.advisory_only);
473    }
474
475    #[test]
476    fn stability_score_contract_keeps_deterministic_component() {
477        let stability = summarize_cascade_stability_score(0.75);
478
479        assert_eq!(stability.schema_version, "0");
480        assert_eq!(stability.layer_marker, "statistical-mechanics");
481        assert!(stability.deterministic_component_passed);
482        assert!(stability.advisory_only);
483    }
484
485    #[test]
486    fn ultrametricity_test_enforces_theorem_fixture() {
487        assert!(prove_strong_triangle_inequality(2, 3, 3));
488        assert!(prove_ultrametric_isomorphism(&[0, 2, 2]));
489    }
490
491    #[test]
492    fn spin_glass_ultrametric_corpus_enforces_five_tier_strong_triangle() {
493        let corpus = verify_spin_glass_ultrametric_corpus_v0();
494
495        assert_eq!(corpus.schema_version, "0");
496        assert_eq!(
497            corpus.product,
498            "omena-cascade.spin-glass-ultrametric-corpus"
499        );
500        assert_eq!(corpus.layer_marker, "statistical-mechanics");
501        assert_eq!(corpus.feature_gate, "spin-glass");
502        assert_eq!(corpus.path_count, 32);
503        assert_eq!(corpus.triple_count, 32 * 32 * 32);
504        assert_eq!(corpus.max_distance, 5);
505        assert!(corpus.exhaustive_binary_five_tier_domain);
506        assert!(corpus.strong_triangle_passed);
507
508        let same_origin = CascadeUltrametricPathV0 {
509            origin: 0,
510            layer: 0,
511            scope: 0,
512            rule: 0,
513            declaration: 0,
514        };
515        let sibling_declaration = CascadeUltrametricPathV0 {
516            origin: 0,
517            layer: 0,
518            scope: 0,
519            rule: 0,
520            declaration: 1,
521        };
522        let different_origin = CascadeUltrametricPathV0 {
523            origin: 1,
524            layer: 0,
525            scope: 0,
526            rule: 0,
527            declaration: 0,
528        };
529
530        assert_eq!(
531            cascade_ultrametric_distance_v0(same_origin, sibling_declaration),
532            1
533        );
534        assert_eq!(
535            cascade_ultrametric_distance_v0(same_origin, different_origin),
536            5
537        );
538        assert!(prove_cascade_ultrametric_strong_triangle_v0(
539            same_origin,
540            sibling_declaration,
541            different_origin
542        ));
543    }
544}