Skip to main content

uor_foundation/kernel/
convergence.rs

1// @generated by uor-crate from uor-ontology — do not edit manually
2
3//! `convergence/` namespace — Hopf convergence tower: four levels R, C, H, O corresponding to the four normed division algebras of dimensions 1, 2, 4, 8. Each level carries a Hopf fibration fiber and Betti signature..
4//!
5//! Space: Kernel
6
7use crate::HostTypes;
8
9/// A level in the convergence tower. Four instances: R (dim 1), C (dim 2), H (dim 4), O (dim 8).
10pub trait ConvergenceLevel<H: HostTypes> {
11    /// The dimension of the division algebra at this level (1, 2, 4, or 8).
12    fn algebra_dimension(&self) -> u64;
13    /// The Betti number signature at this convergence level.
14    fn betti_signature(&self) -> &H::HostString;
15    /// Associated type for `HopfFiber`.
16    type HopfFiber: HopfFiber<H>;
17    /// The Hopf fiber associated with this convergence level.
18    fn fiber_type(&self) -> &Self::HopfFiber;
19    /// The characteristic identity at this convergence level (existence, feedback, choice, self-reference).
20    fn characteristic_identity(&self) -> &H::HostString;
21    /// Human-readable name of this convergence level.
22    fn level_name(&self) -> &H::HostString;
23}
24
25/// The fiber of the Hopf fibration at a convergence level. Four instances: S⁰, S¹, S³, S⁷.
26pub trait HopfFiber<H: HostTypes> {
27    /// The dimension of the Hopf fiber sphere.
28    fn fiber_dimension(&self) -> u64;
29    /// The total space of the Hopf fibration.
30    fn total_space(&self) -> &H::HostString;
31    /// The base space of the Hopf fibration.
32    fn base_space(&self) -> &H::HostString;
33    /// The fiber sphere designation (e.g. S⁰, S¹).
34    fn fiber_sphere(&self) -> &H::HostString;
35}
36
37/// The unresolved structure at a convergence level. The β_{2^k−1} = 1 Betti number that persists.
38pub trait ConvergenceResidual<H: HostTypes> {
39    /// The persistent Betti number at this residual.
40    fn residual_betti(&self) -> u64;
41    /// The dimension at which the residual persists.
42    fn residual_dimension(&self) -> u64;
43}
44
45/// The subspace U(1) ⊂ SU(2) selected when pairwise interaction converges.
46pub trait CommutativeSubspace<H: HostTypes> {
47    /// Associated type for `CommutativeSubspace`.
48    type CommutativeSubspaceTarget: CommutativeSubspace<H>;
49    /// The commutative subspace selected by pairwise convergence.
50    fn subspace_ref(&self) -> &Self::CommutativeSubspaceTarget;
51    /// Associated type for `Commutator`.
52    type Commutator: crate::bridge::observable::Commutator<H>;
53    /// Reference to the commutator pair for this convergence.
54    fn commutator_ref(&self) -> &Self::Commutator;
55}
56
57/// The subspace H ⊂ O selected when triple interaction converges.
58pub trait AssociativeSubalgebra<H: HostTypes> {
59    /// Associated type for `AssociativeSubalgebra`.
60    type AssociativeSubalgebraTarget: AssociativeSubalgebra<H>;
61    /// The associative subalgebra selected by triple convergence.
62    fn subalgebra_ref(&self) -> &Self::AssociativeSubalgebraTarget;
63    /// Associated type for `AssociatorTriple`.
64    type AssociatorTriple: crate::bridge::interaction::AssociatorTriple<H>;
65    /// Reference to the associator triple for this convergence.
66    fn associator_ref(&self) -> &Self::AssociatorTriple;
67}
68
69/// Phase 2 (orphan-closure) — resolver-absent default impl of `ConvergenceLevel<H>`.
70/// Every accessor returns `H::EMPTY_*` sentinels (for scalar / host-typed
71/// returns) or a `'static`-lifetime reference to a sibling `Null*`'s `ABSENT`
72/// const (for trait-typed returns).  Downstream provides concrete impls;
73/// this stub closes the ontology-derived trait orphan.
74#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
75pub struct NullConvergenceLevel<H: HostTypes> {
76    _phantom: core::marker::PhantomData<H>,
77}
78impl<H: HostTypes> Default for NullConvergenceLevel<H> {
79    fn default() -> Self {
80        Self {
81            _phantom: core::marker::PhantomData,
82        }
83    }
84}
85impl<H: HostTypes> NullConvergenceLevel<H> {
86    /// Absent-value sentinel. `&Self::ABSENT` gives every trait-typed accessor a `'static`-lifetime reference target.
87    pub const ABSENT: NullConvergenceLevel<H> = NullConvergenceLevel {
88        _phantom: core::marker::PhantomData,
89    };
90}
91impl<H: HostTypes> ConvergenceLevel<H> for NullConvergenceLevel<H> {
92    fn algebra_dimension(&self) -> u64 {
93        0
94    }
95    fn betti_signature(&self) -> &H::HostString {
96        H::EMPTY_HOST_STRING
97    }
98    type HopfFiber = NullHopfFiber<H>;
99    fn fiber_type(&self) -> &Self::HopfFiber {
100        &<NullHopfFiber<H>>::ABSENT
101    }
102    fn characteristic_identity(&self) -> &H::HostString {
103        H::EMPTY_HOST_STRING
104    }
105    fn level_name(&self) -> &H::HostString {
106        H::EMPTY_HOST_STRING
107    }
108}
109
110/// Phase 2 (orphan-closure) — resolver-absent default impl of `HopfFiber<H>`.
111/// Every accessor returns `H::EMPTY_*` sentinels (for scalar / host-typed
112/// returns) or a `'static`-lifetime reference to a sibling `Null*`'s `ABSENT`
113/// const (for trait-typed returns).  Downstream provides concrete impls;
114/// this stub closes the ontology-derived trait orphan.
115#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
116pub struct NullHopfFiber<H: HostTypes> {
117    _phantom: core::marker::PhantomData<H>,
118}
119impl<H: HostTypes> Default for NullHopfFiber<H> {
120    fn default() -> Self {
121        Self {
122            _phantom: core::marker::PhantomData,
123        }
124    }
125}
126impl<H: HostTypes> NullHopfFiber<H> {
127    /// Absent-value sentinel. `&Self::ABSENT` gives every trait-typed accessor a `'static`-lifetime reference target.
128    pub const ABSENT: NullHopfFiber<H> = NullHopfFiber {
129        _phantom: core::marker::PhantomData,
130    };
131}
132impl<H: HostTypes> HopfFiber<H> for NullHopfFiber<H> {
133    fn fiber_dimension(&self) -> u64 {
134        0
135    }
136    fn total_space(&self) -> &H::HostString {
137        H::EMPTY_HOST_STRING
138    }
139    fn base_space(&self) -> &H::HostString {
140        H::EMPTY_HOST_STRING
141    }
142    fn fiber_sphere(&self) -> &H::HostString {
143        H::EMPTY_HOST_STRING
144    }
145}
146
147/// Phase 2 (orphan-closure) — resolver-absent default impl of `ConvergenceResidual<H>`.
148/// Every accessor returns `H::EMPTY_*` sentinels (for scalar / host-typed
149/// returns) or a `'static`-lifetime reference to a sibling `Null*`'s `ABSENT`
150/// const (for trait-typed returns).  Downstream provides concrete impls;
151/// this stub closes the ontology-derived trait orphan.
152#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
153pub struct NullConvergenceResidual<H: HostTypes> {
154    _phantom: core::marker::PhantomData<H>,
155}
156impl<H: HostTypes> Default for NullConvergenceResidual<H> {
157    fn default() -> Self {
158        Self {
159            _phantom: core::marker::PhantomData,
160        }
161    }
162}
163impl<H: HostTypes> NullConvergenceResidual<H> {
164    /// Absent-value sentinel. `&Self::ABSENT` gives every trait-typed accessor a `'static`-lifetime reference target.
165    pub const ABSENT: NullConvergenceResidual<H> = NullConvergenceResidual {
166        _phantom: core::marker::PhantomData,
167    };
168}
169impl<H: HostTypes> ConvergenceResidual<H> for NullConvergenceResidual<H> {
170    fn residual_betti(&self) -> u64 {
171        0
172    }
173    fn residual_dimension(&self) -> u64 {
174        0
175    }
176}
177
178/// Phase 2 (orphan-closure) — resolver-absent default impl of `CommutativeSubspace<H>`.
179/// Every accessor returns `H::EMPTY_*` sentinels (for scalar / host-typed
180/// returns) or a `'static`-lifetime reference to a sibling `Null*`'s `ABSENT`
181/// const (for trait-typed returns).  Downstream provides concrete impls;
182/// this stub closes the ontology-derived trait orphan.
183#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
184pub struct NullCommutativeSubspace<H: HostTypes> {
185    _phantom: core::marker::PhantomData<H>,
186}
187impl<H: HostTypes> Default for NullCommutativeSubspace<H> {
188    fn default() -> Self {
189        Self {
190            _phantom: core::marker::PhantomData,
191        }
192    }
193}
194impl<H: HostTypes> NullCommutativeSubspace<H> {
195    /// Absent-value sentinel. `&Self::ABSENT` gives every trait-typed accessor a `'static`-lifetime reference target.
196    pub const ABSENT: NullCommutativeSubspace<H> = NullCommutativeSubspace {
197        _phantom: core::marker::PhantomData,
198    };
199}
200impl<H: HostTypes> CommutativeSubspace<H> for NullCommutativeSubspace<H> {
201    type CommutativeSubspaceTarget = NullCommutativeSubspace<H>;
202    fn subspace_ref(&self) -> &Self::CommutativeSubspaceTarget {
203        &<NullCommutativeSubspace<H>>::ABSENT
204    }
205    type Commutator = crate::bridge::observable::NullCommutator<H>;
206    fn commutator_ref(&self) -> &Self::Commutator {
207        &<crate::bridge::observable::NullCommutator<H>>::ABSENT
208    }
209}
210
211/// Phase 2 (orphan-closure) — resolver-absent default impl of `AssociativeSubalgebra<H>`.
212/// Every accessor returns `H::EMPTY_*` sentinels (for scalar / host-typed
213/// returns) or a `'static`-lifetime reference to a sibling `Null*`'s `ABSENT`
214/// const (for trait-typed returns).  Downstream provides concrete impls;
215/// this stub closes the ontology-derived trait orphan.
216#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
217pub struct NullAssociativeSubalgebra<H: HostTypes> {
218    _phantom: core::marker::PhantomData<H>,
219}
220impl<H: HostTypes> Default for NullAssociativeSubalgebra<H> {
221    fn default() -> Self {
222        Self {
223            _phantom: core::marker::PhantomData,
224        }
225    }
226}
227impl<H: HostTypes> NullAssociativeSubalgebra<H> {
228    /// Absent-value sentinel. `&Self::ABSENT` gives every trait-typed accessor a `'static`-lifetime reference target.
229    pub const ABSENT: NullAssociativeSubalgebra<H> = NullAssociativeSubalgebra {
230        _phantom: core::marker::PhantomData,
231    };
232}
233impl<H: HostTypes> AssociativeSubalgebra<H> for NullAssociativeSubalgebra<H> {
234    type AssociativeSubalgebraTarget = NullAssociativeSubalgebra<H>;
235    fn subalgebra_ref(&self) -> &Self::AssociativeSubalgebraTarget {
236        &<NullAssociativeSubalgebra<H>>::ABSENT
237    }
238    type AssociatorTriple = crate::bridge::interaction::NullAssociatorTriple<H>;
239    fn associator_ref(&self) -> &Self::AssociatorTriple {
240        &<crate::bridge::interaction::NullAssociatorTriple<H>>::ABSENT
241    }
242}
243
244/// Phase 8 (orphan-closure) — content-addressed handle for `ConvergenceLevel<H>`.
245///
246/// Pairs a [`crate::enforcement::ContentFingerprint`] with a phantom
247/// `H` so type-state checks can't mix handles across `HostTypes` impls.
248#[derive(Debug)]
249pub struct ConvergenceLevelHandle<H: HostTypes> {
250    /// Content fingerprint identifying the resolved record.
251    pub fingerprint: crate::enforcement::ContentFingerprint,
252    _phantom: core::marker::PhantomData<H>,
253}
254impl<H: HostTypes> Copy for ConvergenceLevelHandle<H> {}
255impl<H: HostTypes> Clone for ConvergenceLevelHandle<H> {
256    #[inline]
257    fn clone(&self) -> Self {
258        *self
259    }
260}
261impl<H: HostTypes> PartialEq for ConvergenceLevelHandle<H> {
262    #[inline]
263    fn eq(&self, other: &Self) -> bool {
264        self.fingerprint == other.fingerprint
265    }
266}
267impl<H: HostTypes> Eq for ConvergenceLevelHandle<H> {}
268impl<H: HostTypes> core::hash::Hash for ConvergenceLevelHandle<H> {
269    #[inline]
270    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
271        self.fingerprint.hash(state);
272    }
273}
274impl<H: HostTypes> ConvergenceLevelHandle<H> {
275    /// Construct a handle from its content fingerprint.
276    #[inline]
277    #[must_use]
278    pub const fn new(fingerprint: crate::enforcement::ContentFingerprint) -> Self {
279        Self {
280            fingerprint,
281            _phantom: core::marker::PhantomData,
282        }
283    }
284}
285
286/// Phase 8 (orphan-closure) — resolver trait for `ConvergenceLevel<H>`.
287///
288/// Hosts implement this trait to map a handle into a typed record.
289/// The default Null stub does not implement this trait — it carries
290/// no record. Resolution is the responsibility of the host pipeline.
291pub trait ConvergenceLevelResolver<H: HostTypes> {
292    /// Resolve a handle into its record. Returns `None` when the
293    /// handle does not correspond to known content.
294    fn resolve(&self, handle: ConvergenceLevelHandle<H>) -> Option<ConvergenceLevelRecord<H>>;
295}
296
297/// Phase 8 (orphan-closure) — typed record for `ConvergenceLevel<H>`.
298///
299/// Carries a field per functional accessor of the trait. Object
300/// fields hold `{Range}Handle<H>`; iterate via the Resolved wrapper
301/// chain-resolver methods.
302#[derive(Clone, Debug, PartialEq, Eq, Hash)]
303pub struct ConvergenceLevelRecord<H: HostTypes> {
304    pub algebra_dimension: u64,
305    pub betti_signature: &'static H::HostString,
306    pub fiber_type_handle: HopfFiberHandle<H>,
307    pub characteristic_identity: &'static H::HostString,
308    pub level_name: &'static H::HostString,
309    #[doc(hidden)]
310    pub _phantom: core::marker::PhantomData<H>,
311}
312
313/// Phase 8 (orphan-closure) — content-addressed wrapper for `ConvergenceLevel<H>`.
314///
315/// Caches the resolver's lookup at construction. Accessors return
316/// the cached record's fields when present, falling back to the
317/// `Null{Class}<H>` absent sentinels when the resolver returned
318/// `None`. Object accessors always return absent sentinels — use
319/// the `resolve_{m}` chain methods to descend into sub-records.
320pub struct ResolvedConvergenceLevel<'r, R: ConvergenceLevelResolver<H>, H: HostTypes> {
321    handle: ConvergenceLevelHandle<H>,
322    resolver: &'r R,
323    record: Option<ConvergenceLevelRecord<H>>,
324}
325impl<'r, R: ConvergenceLevelResolver<H>, H: HostTypes> ResolvedConvergenceLevel<'r, R, H> {
326    /// Construct the wrapper, eagerly resolving the handle.
327    #[inline]
328    pub fn new(handle: ConvergenceLevelHandle<H>, resolver: &'r R) -> Self {
329        let record = resolver.resolve(handle);
330        Self {
331            handle,
332            resolver,
333            record,
334        }
335    }
336    /// The handle this wrapper resolves.
337    #[inline]
338    #[must_use]
339    pub const fn handle(&self) -> ConvergenceLevelHandle<H> {
340        self.handle
341    }
342    /// The resolver supplied at construction.
343    #[inline]
344    #[must_use]
345    pub const fn resolver(&self) -> &'r R {
346        self.resolver
347    }
348    /// The cached record, or `None` when the resolver returned `None`.
349    #[inline]
350    #[must_use]
351    pub const fn record(&self) -> Option<&ConvergenceLevelRecord<H>> {
352        self.record.as_ref()
353    }
354}
355impl<'r, R: ConvergenceLevelResolver<H>, H: HostTypes> ConvergenceLevel<H>
356    for ResolvedConvergenceLevel<'r, R, H>
357{
358    fn algebra_dimension(&self) -> u64 {
359        match &self.record {
360            Some(r) => r.algebra_dimension,
361            None => 0,
362        }
363    }
364    fn betti_signature(&self) -> &H::HostString {
365        match &self.record {
366            Some(r) => r.betti_signature,
367            None => H::EMPTY_HOST_STRING,
368        }
369    }
370    type HopfFiber = NullHopfFiber<H>;
371    fn fiber_type(&self) -> &Self::HopfFiber {
372        &<NullHopfFiber<H>>::ABSENT
373    }
374    fn characteristic_identity(&self) -> &H::HostString {
375        match &self.record {
376            Some(r) => r.characteristic_identity,
377            None => H::EMPTY_HOST_STRING,
378        }
379    }
380    fn level_name(&self) -> &H::HostString {
381        match &self.record {
382            Some(r) => r.level_name,
383            None => H::EMPTY_HOST_STRING,
384        }
385    }
386}
387impl<'r, R: ConvergenceLevelResolver<H>, H: HostTypes> ResolvedConvergenceLevel<'r, R, H> {
388    /// Promote the `fiber_type` handle on the cached record into a
389    /// resolved wrapper, given a resolver for the range class.
390    /// Returns `None` if no record was resolved at construction.
391    #[inline]
392    pub fn resolve_fiber_type<'r2, R2: HopfFiberResolver<H>>(
393        &self,
394        r: &'r2 R2,
395    ) -> Option<ResolvedHopfFiber<'r2, R2, H>> {
396        let record = self.record.as_ref()?;
397        Some(ResolvedHopfFiber::new(record.fiber_type_handle, r))
398    }
399}
400
401/// Phase 8 (orphan-closure) — content-addressed handle for `HopfFiber<H>`.
402///
403/// Pairs a [`crate::enforcement::ContentFingerprint`] with a phantom
404/// `H` so type-state checks can't mix handles across `HostTypes` impls.
405#[derive(Debug)]
406pub struct HopfFiberHandle<H: HostTypes> {
407    /// Content fingerprint identifying the resolved record.
408    pub fingerprint: crate::enforcement::ContentFingerprint,
409    _phantom: core::marker::PhantomData<H>,
410}
411impl<H: HostTypes> Copy for HopfFiberHandle<H> {}
412impl<H: HostTypes> Clone for HopfFiberHandle<H> {
413    #[inline]
414    fn clone(&self) -> Self {
415        *self
416    }
417}
418impl<H: HostTypes> PartialEq for HopfFiberHandle<H> {
419    #[inline]
420    fn eq(&self, other: &Self) -> bool {
421        self.fingerprint == other.fingerprint
422    }
423}
424impl<H: HostTypes> Eq for HopfFiberHandle<H> {}
425impl<H: HostTypes> core::hash::Hash for HopfFiberHandle<H> {
426    #[inline]
427    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
428        self.fingerprint.hash(state);
429    }
430}
431impl<H: HostTypes> HopfFiberHandle<H> {
432    /// Construct a handle from its content fingerprint.
433    #[inline]
434    #[must_use]
435    pub const fn new(fingerprint: crate::enforcement::ContentFingerprint) -> Self {
436        Self {
437            fingerprint,
438            _phantom: core::marker::PhantomData,
439        }
440    }
441}
442
443/// Phase 8 (orphan-closure) — resolver trait for `HopfFiber<H>`.
444///
445/// Hosts implement this trait to map a handle into a typed record.
446/// The default Null stub does not implement this trait — it carries
447/// no record. Resolution is the responsibility of the host pipeline.
448pub trait HopfFiberResolver<H: HostTypes> {
449    /// Resolve a handle into its record. Returns `None` when the
450    /// handle does not correspond to known content.
451    fn resolve(&self, handle: HopfFiberHandle<H>) -> Option<HopfFiberRecord<H>>;
452}
453
454/// Phase 8 (orphan-closure) — typed record for `HopfFiber<H>`.
455///
456/// Carries a field per functional accessor of the trait. Object
457/// fields hold `{Range}Handle<H>`; iterate via the Resolved wrapper
458/// chain-resolver methods.
459#[derive(Clone, Debug, PartialEq, Eq, Hash)]
460pub struct HopfFiberRecord<H: HostTypes> {
461    pub fiber_dimension: u64,
462    pub total_space: &'static H::HostString,
463    pub base_space: &'static H::HostString,
464    pub fiber_sphere: &'static H::HostString,
465    #[doc(hidden)]
466    pub _phantom: core::marker::PhantomData<H>,
467}
468
469/// Phase 8 (orphan-closure) — content-addressed wrapper for `HopfFiber<H>`.
470///
471/// Caches the resolver's lookup at construction. Accessors return
472/// the cached record's fields when present, falling back to the
473/// `Null{Class}<H>` absent sentinels when the resolver returned
474/// `None`. Object accessors always return absent sentinels — use
475/// the `resolve_{m}` chain methods to descend into sub-records.
476pub struct ResolvedHopfFiber<'r, R: HopfFiberResolver<H>, H: HostTypes> {
477    handle: HopfFiberHandle<H>,
478    resolver: &'r R,
479    record: Option<HopfFiberRecord<H>>,
480}
481impl<'r, R: HopfFiberResolver<H>, H: HostTypes> ResolvedHopfFiber<'r, R, H> {
482    /// Construct the wrapper, eagerly resolving the handle.
483    #[inline]
484    pub fn new(handle: HopfFiberHandle<H>, resolver: &'r R) -> Self {
485        let record = resolver.resolve(handle);
486        Self {
487            handle,
488            resolver,
489            record,
490        }
491    }
492    /// The handle this wrapper resolves.
493    #[inline]
494    #[must_use]
495    pub const fn handle(&self) -> HopfFiberHandle<H> {
496        self.handle
497    }
498    /// The resolver supplied at construction.
499    #[inline]
500    #[must_use]
501    pub const fn resolver(&self) -> &'r R {
502        self.resolver
503    }
504    /// The cached record, or `None` when the resolver returned `None`.
505    #[inline]
506    #[must_use]
507    pub const fn record(&self) -> Option<&HopfFiberRecord<H>> {
508        self.record.as_ref()
509    }
510}
511impl<'r, R: HopfFiberResolver<H>, H: HostTypes> HopfFiber<H> for ResolvedHopfFiber<'r, R, H> {
512    fn fiber_dimension(&self) -> u64 {
513        match &self.record {
514            Some(r) => r.fiber_dimension,
515            None => 0,
516        }
517    }
518    fn total_space(&self) -> &H::HostString {
519        match &self.record {
520            Some(r) => r.total_space,
521            None => H::EMPTY_HOST_STRING,
522        }
523    }
524    fn base_space(&self) -> &H::HostString {
525        match &self.record {
526            Some(r) => r.base_space,
527            None => H::EMPTY_HOST_STRING,
528        }
529    }
530    fn fiber_sphere(&self) -> &H::HostString {
531        match &self.record {
532            Some(r) => r.fiber_sphere,
533            None => H::EMPTY_HOST_STRING,
534        }
535    }
536}
537
538/// Phase 8 (orphan-closure) — content-addressed handle for `ConvergenceResidual<H>`.
539///
540/// Pairs a [`crate::enforcement::ContentFingerprint`] with a phantom
541/// `H` so type-state checks can't mix handles across `HostTypes` impls.
542#[derive(Debug)]
543pub struct ConvergenceResidualHandle<H: HostTypes> {
544    /// Content fingerprint identifying the resolved record.
545    pub fingerprint: crate::enforcement::ContentFingerprint,
546    _phantom: core::marker::PhantomData<H>,
547}
548impl<H: HostTypes> Copy for ConvergenceResidualHandle<H> {}
549impl<H: HostTypes> Clone for ConvergenceResidualHandle<H> {
550    #[inline]
551    fn clone(&self) -> Self {
552        *self
553    }
554}
555impl<H: HostTypes> PartialEq for ConvergenceResidualHandle<H> {
556    #[inline]
557    fn eq(&self, other: &Self) -> bool {
558        self.fingerprint == other.fingerprint
559    }
560}
561impl<H: HostTypes> Eq for ConvergenceResidualHandle<H> {}
562impl<H: HostTypes> core::hash::Hash for ConvergenceResidualHandle<H> {
563    #[inline]
564    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
565        self.fingerprint.hash(state);
566    }
567}
568impl<H: HostTypes> ConvergenceResidualHandle<H> {
569    /// Construct a handle from its content fingerprint.
570    #[inline]
571    #[must_use]
572    pub const fn new(fingerprint: crate::enforcement::ContentFingerprint) -> Self {
573        Self {
574            fingerprint,
575            _phantom: core::marker::PhantomData,
576        }
577    }
578}
579
580/// Phase 8 (orphan-closure) — resolver trait for `ConvergenceResidual<H>`.
581///
582/// Hosts implement this trait to map a handle into a typed record.
583/// The default Null stub does not implement this trait — it carries
584/// no record. Resolution is the responsibility of the host pipeline.
585pub trait ConvergenceResidualResolver<H: HostTypes> {
586    /// Resolve a handle into its record. Returns `None` when the
587    /// handle does not correspond to known content.
588    fn resolve(&self, handle: ConvergenceResidualHandle<H>)
589        -> Option<ConvergenceResidualRecord<H>>;
590}
591
592/// Phase 8 (orphan-closure) — typed record for `ConvergenceResidual<H>`.
593///
594/// Carries a field per functional accessor of the trait. Object
595/// fields hold `{Range}Handle<H>`; iterate via the Resolved wrapper
596/// chain-resolver methods.
597#[derive(Clone, Debug, PartialEq, Eq, Hash)]
598pub struct ConvergenceResidualRecord<H: HostTypes> {
599    pub residual_betti: u64,
600    pub residual_dimension: u64,
601    #[doc(hidden)]
602    pub _phantom: core::marker::PhantomData<H>,
603}
604
605/// Phase 8 (orphan-closure) — content-addressed wrapper for `ConvergenceResidual<H>`.
606///
607/// Caches the resolver's lookup at construction. Accessors return
608/// the cached record's fields when present, falling back to the
609/// `Null{Class}<H>` absent sentinels when the resolver returned
610/// `None`. Object accessors always return absent sentinels — use
611/// the `resolve_{m}` chain methods to descend into sub-records.
612pub struct ResolvedConvergenceResidual<'r, R: ConvergenceResidualResolver<H>, H: HostTypes> {
613    handle: ConvergenceResidualHandle<H>,
614    resolver: &'r R,
615    record: Option<ConvergenceResidualRecord<H>>,
616}
617impl<'r, R: ConvergenceResidualResolver<H>, H: HostTypes> ResolvedConvergenceResidual<'r, R, H> {
618    /// Construct the wrapper, eagerly resolving the handle.
619    #[inline]
620    pub fn new(handle: ConvergenceResidualHandle<H>, resolver: &'r R) -> Self {
621        let record = resolver.resolve(handle);
622        Self {
623            handle,
624            resolver,
625            record,
626        }
627    }
628    /// The handle this wrapper resolves.
629    #[inline]
630    #[must_use]
631    pub const fn handle(&self) -> ConvergenceResidualHandle<H> {
632        self.handle
633    }
634    /// The resolver supplied at construction.
635    #[inline]
636    #[must_use]
637    pub const fn resolver(&self) -> &'r R {
638        self.resolver
639    }
640    /// The cached record, or `None` when the resolver returned `None`.
641    #[inline]
642    #[must_use]
643    pub const fn record(&self) -> Option<&ConvergenceResidualRecord<H>> {
644        self.record.as_ref()
645    }
646}
647impl<'r, R: ConvergenceResidualResolver<H>, H: HostTypes> ConvergenceResidual<H>
648    for ResolvedConvergenceResidual<'r, R, H>
649{
650    fn residual_betti(&self) -> u64 {
651        match &self.record {
652            Some(r) => r.residual_betti,
653            None => 0,
654        }
655    }
656    fn residual_dimension(&self) -> u64 {
657        match &self.record {
658            Some(r) => r.residual_dimension,
659            None => 0,
660        }
661    }
662}
663
664/// Phase 8 (orphan-closure) — content-addressed handle for `CommutativeSubspace<H>`.
665///
666/// Pairs a [`crate::enforcement::ContentFingerprint`] with a phantom
667/// `H` so type-state checks can't mix handles across `HostTypes` impls.
668#[derive(Debug)]
669pub struct CommutativeSubspaceHandle<H: HostTypes> {
670    /// Content fingerprint identifying the resolved record.
671    pub fingerprint: crate::enforcement::ContentFingerprint,
672    _phantom: core::marker::PhantomData<H>,
673}
674impl<H: HostTypes> Copy for CommutativeSubspaceHandle<H> {}
675impl<H: HostTypes> Clone for CommutativeSubspaceHandle<H> {
676    #[inline]
677    fn clone(&self) -> Self {
678        *self
679    }
680}
681impl<H: HostTypes> PartialEq for CommutativeSubspaceHandle<H> {
682    #[inline]
683    fn eq(&self, other: &Self) -> bool {
684        self.fingerprint == other.fingerprint
685    }
686}
687impl<H: HostTypes> Eq for CommutativeSubspaceHandle<H> {}
688impl<H: HostTypes> core::hash::Hash for CommutativeSubspaceHandle<H> {
689    #[inline]
690    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
691        self.fingerprint.hash(state);
692    }
693}
694impl<H: HostTypes> CommutativeSubspaceHandle<H> {
695    /// Construct a handle from its content fingerprint.
696    #[inline]
697    #[must_use]
698    pub const fn new(fingerprint: crate::enforcement::ContentFingerprint) -> Self {
699        Self {
700            fingerprint,
701            _phantom: core::marker::PhantomData,
702        }
703    }
704}
705
706/// Phase 8 (orphan-closure) — resolver trait for `CommutativeSubspace<H>`.
707///
708/// Hosts implement this trait to map a handle into a typed record.
709/// The default Null stub does not implement this trait — it carries
710/// no record. Resolution is the responsibility of the host pipeline.
711pub trait CommutativeSubspaceResolver<H: HostTypes> {
712    /// Resolve a handle into its record. Returns `None` when the
713    /// handle does not correspond to known content.
714    fn resolve(&self, handle: CommutativeSubspaceHandle<H>)
715        -> Option<CommutativeSubspaceRecord<H>>;
716}
717
718/// Phase 8 (orphan-closure) — typed record for `CommutativeSubspace<H>`.
719///
720/// Carries a field per functional accessor of the trait. Object
721/// fields hold `{Range}Handle<H>`; iterate via the Resolved wrapper
722/// chain-resolver methods.
723#[derive(Clone, Debug, PartialEq, Eq, Hash)]
724pub struct CommutativeSubspaceRecord<H: HostTypes> {
725    pub subspace_ref_handle: CommutativeSubspaceHandle<H>,
726    pub commutator_ref_handle: crate::bridge::observable::CommutatorHandle<H>,
727    #[doc(hidden)]
728    pub _phantom: core::marker::PhantomData<H>,
729}
730
731/// Phase 8 (orphan-closure) — content-addressed wrapper for `CommutativeSubspace<H>`.
732///
733/// Caches the resolver's lookup at construction. Accessors return
734/// the cached record's fields when present, falling back to the
735/// `Null{Class}<H>` absent sentinels when the resolver returned
736/// `None`. Object accessors always return absent sentinels — use
737/// the `resolve_{m}` chain methods to descend into sub-records.
738pub struct ResolvedCommutativeSubspace<'r, R: CommutativeSubspaceResolver<H>, H: HostTypes> {
739    handle: CommutativeSubspaceHandle<H>,
740    resolver: &'r R,
741    record: Option<CommutativeSubspaceRecord<H>>,
742}
743impl<'r, R: CommutativeSubspaceResolver<H>, H: HostTypes> ResolvedCommutativeSubspace<'r, R, H> {
744    /// Construct the wrapper, eagerly resolving the handle.
745    #[inline]
746    pub fn new(handle: CommutativeSubspaceHandle<H>, resolver: &'r R) -> Self {
747        let record = resolver.resolve(handle);
748        Self {
749            handle,
750            resolver,
751            record,
752        }
753    }
754    /// The handle this wrapper resolves.
755    #[inline]
756    #[must_use]
757    pub const fn handle(&self) -> CommutativeSubspaceHandle<H> {
758        self.handle
759    }
760    /// The resolver supplied at construction.
761    #[inline]
762    #[must_use]
763    pub const fn resolver(&self) -> &'r R {
764        self.resolver
765    }
766    /// The cached record, or `None` when the resolver returned `None`.
767    #[inline]
768    #[must_use]
769    pub const fn record(&self) -> Option<&CommutativeSubspaceRecord<H>> {
770        self.record.as_ref()
771    }
772}
773impl<'r, R: CommutativeSubspaceResolver<H>, H: HostTypes> CommutativeSubspace<H>
774    for ResolvedCommutativeSubspace<'r, R, H>
775{
776    type CommutativeSubspaceTarget = NullCommutativeSubspace<H>;
777    fn subspace_ref(&self) -> &Self::CommutativeSubspaceTarget {
778        &<NullCommutativeSubspace<H>>::ABSENT
779    }
780    type Commutator = crate::bridge::observable::NullCommutator<H>;
781    fn commutator_ref(&self) -> &Self::Commutator {
782        &<crate::bridge::observable::NullCommutator<H>>::ABSENT
783    }
784}
785impl<'r, R: CommutativeSubspaceResolver<H>, H: HostTypes> ResolvedCommutativeSubspace<'r, R, H> {
786    /// Promote the `subspace_ref` handle on the cached record into a
787    /// resolved wrapper, given a resolver for the range class.
788    /// Returns `None` if no record was resolved at construction.
789    #[inline]
790    pub fn resolve_subspace_ref<'r2, R2: CommutativeSubspaceResolver<H>>(
791        &self,
792        r: &'r2 R2,
793    ) -> Option<ResolvedCommutativeSubspace<'r2, R2, H>> {
794        let record = self.record.as_ref()?;
795        Some(ResolvedCommutativeSubspace::new(
796            record.subspace_ref_handle,
797            r,
798        ))
799    }
800    /// Promote the `commutator_ref` handle on the cached record into a
801    /// resolved wrapper, given a resolver for the range class.
802    /// Returns `None` if no record was resolved at construction.
803    #[inline]
804    pub fn resolve_commutator_ref<'r2, R2: crate::bridge::observable::CommutatorResolver<H>>(
805        &self,
806        r: &'r2 R2,
807    ) -> Option<crate::bridge::observable::ResolvedCommutator<'r2, R2, H>> {
808        let record = self.record.as_ref()?;
809        Some(crate::bridge::observable::ResolvedCommutator::new(
810            record.commutator_ref_handle,
811            r,
812        ))
813    }
814}
815
816/// Phase 8 (orphan-closure) — content-addressed handle for `AssociativeSubalgebra<H>`.
817///
818/// Pairs a [`crate::enforcement::ContentFingerprint`] with a phantom
819/// `H` so type-state checks can't mix handles across `HostTypes` impls.
820#[derive(Debug)]
821pub struct AssociativeSubalgebraHandle<H: HostTypes> {
822    /// Content fingerprint identifying the resolved record.
823    pub fingerprint: crate::enforcement::ContentFingerprint,
824    _phantom: core::marker::PhantomData<H>,
825}
826impl<H: HostTypes> Copy for AssociativeSubalgebraHandle<H> {}
827impl<H: HostTypes> Clone for AssociativeSubalgebraHandle<H> {
828    #[inline]
829    fn clone(&self) -> Self {
830        *self
831    }
832}
833impl<H: HostTypes> PartialEq for AssociativeSubalgebraHandle<H> {
834    #[inline]
835    fn eq(&self, other: &Self) -> bool {
836        self.fingerprint == other.fingerprint
837    }
838}
839impl<H: HostTypes> Eq for AssociativeSubalgebraHandle<H> {}
840impl<H: HostTypes> core::hash::Hash for AssociativeSubalgebraHandle<H> {
841    #[inline]
842    fn hash<S: core::hash::Hasher>(&self, state: &mut S) {
843        self.fingerprint.hash(state);
844    }
845}
846impl<H: HostTypes> AssociativeSubalgebraHandle<H> {
847    /// Construct a handle from its content fingerprint.
848    #[inline]
849    #[must_use]
850    pub const fn new(fingerprint: crate::enforcement::ContentFingerprint) -> Self {
851        Self {
852            fingerprint,
853            _phantom: core::marker::PhantomData,
854        }
855    }
856}
857
858/// Phase 8 (orphan-closure) — resolver trait for `AssociativeSubalgebra<H>`.
859///
860/// Hosts implement this trait to map a handle into a typed record.
861/// The default Null stub does not implement this trait — it carries
862/// no record. Resolution is the responsibility of the host pipeline.
863pub trait AssociativeSubalgebraResolver<H: HostTypes> {
864    /// Resolve a handle into its record. Returns `None` when the
865    /// handle does not correspond to known content.
866    fn resolve(
867        &self,
868        handle: AssociativeSubalgebraHandle<H>,
869    ) -> Option<AssociativeSubalgebraRecord<H>>;
870}
871
872/// Phase 8 (orphan-closure) — typed record for `AssociativeSubalgebra<H>`.
873///
874/// Carries a field per functional accessor of the trait. Object
875/// fields hold `{Range}Handle<H>`; iterate via the Resolved wrapper
876/// chain-resolver methods.
877#[derive(Clone, Debug, PartialEq, Eq, Hash)]
878pub struct AssociativeSubalgebraRecord<H: HostTypes> {
879    pub subalgebra_ref_handle: AssociativeSubalgebraHandle<H>,
880    pub associator_ref_handle: crate::bridge::interaction::AssociatorTripleHandle<H>,
881    #[doc(hidden)]
882    pub _phantom: core::marker::PhantomData<H>,
883}
884
885/// Phase 8 (orphan-closure) — content-addressed wrapper for `AssociativeSubalgebra<H>`.
886///
887/// Caches the resolver's lookup at construction. Accessors return
888/// the cached record's fields when present, falling back to the
889/// `Null{Class}<H>` absent sentinels when the resolver returned
890/// `None`. Object accessors always return absent sentinels — use
891/// the `resolve_{m}` chain methods to descend into sub-records.
892pub struct ResolvedAssociativeSubalgebra<'r, R: AssociativeSubalgebraResolver<H>, H: HostTypes> {
893    handle: AssociativeSubalgebraHandle<H>,
894    resolver: &'r R,
895    record: Option<AssociativeSubalgebraRecord<H>>,
896}
897impl<'r, R: AssociativeSubalgebraResolver<H>, H: HostTypes>
898    ResolvedAssociativeSubalgebra<'r, R, H>
899{
900    /// Construct the wrapper, eagerly resolving the handle.
901    #[inline]
902    pub fn new(handle: AssociativeSubalgebraHandle<H>, resolver: &'r R) -> Self {
903        let record = resolver.resolve(handle);
904        Self {
905            handle,
906            resolver,
907            record,
908        }
909    }
910    /// The handle this wrapper resolves.
911    #[inline]
912    #[must_use]
913    pub const fn handle(&self) -> AssociativeSubalgebraHandle<H> {
914        self.handle
915    }
916    /// The resolver supplied at construction.
917    #[inline]
918    #[must_use]
919    pub const fn resolver(&self) -> &'r R {
920        self.resolver
921    }
922    /// The cached record, or `None` when the resolver returned `None`.
923    #[inline]
924    #[must_use]
925    pub const fn record(&self) -> Option<&AssociativeSubalgebraRecord<H>> {
926        self.record.as_ref()
927    }
928}
929impl<'r, R: AssociativeSubalgebraResolver<H>, H: HostTypes> AssociativeSubalgebra<H>
930    for ResolvedAssociativeSubalgebra<'r, R, H>
931{
932    type AssociativeSubalgebraTarget = NullAssociativeSubalgebra<H>;
933    fn subalgebra_ref(&self) -> &Self::AssociativeSubalgebraTarget {
934        &<NullAssociativeSubalgebra<H>>::ABSENT
935    }
936    type AssociatorTriple = crate::bridge::interaction::NullAssociatorTriple<H>;
937    fn associator_ref(&self) -> &Self::AssociatorTriple {
938        &<crate::bridge::interaction::NullAssociatorTriple<H>>::ABSENT
939    }
940}
941impl<'r, R: AssociativeSubalgebraResolver<H>, H: HostTypes>
942    ResolvedAssociativeSubalgebra<'r, R, H>
943{
944    /// Promote the `subalgebra_ref` handle on the cached record into a
945    /// resolved wrapper, given a resolver for the range class.
946    /// Returns `None` if no record was resolved at construction.
947    #[inline]
948    pub fn resolve_subalgebra_ref<'r2, R2: AssociativeSubalgebraResolver<H>>(
949        &self,
950        r: &'r2 R2,
951    ) -> Option<ResolvedAssociativeSubalgebra<'r2, R2, H>> {
952        let record = self.record.as_ref()?;
953        Some(ResolvedAssociativeSubalgebra::new(
954            record.subalgebra_ref_handle,
955            r,
956        ))
957    }
958    /// Promote the `associator_ref` handle on the cached record into a
959    /// resolved wrapper, given a resolver for the range class.
960    /// Returns `None` if no record was resolved at construction.
961    #[inline]
962    pub fn resolve_associator_ref<
963        'r2,
964        R2: crate::bridge::interaction::AssociatorTripleResolver<H>,
965    >(
966        &self,
967        r: &'r2 R2,
968    ) -> Option<crate::bridge::interaction::ResolvedAssociatorTriple<'r2, R2, H>> {
969        let record = self.record.as_ref()?;
970        Some(crate::bridge::interaction::ResolvedAssociatorTriple::new(
971            record.associator_ref_handle,
972            r,
973        ))
974    }
975}
976
977/// Level 0: R (reals), dimension 1, existence.
978pub mod l0_state {
979    /// `algebraDimension`
980    pub const ALGEBRA_DIMENSION: i64 = 1;
981    /// `bettiSignature`
982    pub const BETTI_SIGNATURE: &str = "[1]";
983    /// `characteristicIdentity`
984    pub const CHARACTERISTIC_IDENTITY: &str = "existence";
985    /// `fiberType` -> `hopf_S0`
986    pub const FIBER_TYPE: &str = "https://uor.foundation/convergence/hopf_S0";
987    /// `levelName`
988    pub const LEVEL_NAME: &str = "R";
989}
990
991/// Level 1: C (complex), dimension 2, feedback.
992pub mod l1_memory {
993    /// `algebraDimension`
994    pub const ALGEBRA_DIMENSION: i64 = 2;
995    /// `bettiSignature`
996    pub const BETTI_SIGNATURE: &str = "[1,1]";
997    /// `characteristicIdentity`
998    pub const CHARACTERISTIC_IDENTITY: &str = "feedback";
999    /// `fiberType` -> `hopf_S1`
1000    pub const FIBER_TYPE: &str = "https://uor.foundation/convergence/hopf_S1";
1001    /// `levelName`
1002    pub const LEVEL_NAME: &str = "C";
1003}
1004
1005/// Level 2: H (quaternions), dimension 4, choice.
1006pub mod l2_agency {
1007    /// `algebraDimension`
1008    pub const ALGEBRA_DIMENSION: i64 = 4;
1009    /// `bettiSignature`
1010    pub const BETTI_SIGNATURE: &str = "[1,0,0,1]";
1011    /// `characteristicIdentity`
1012    pub const CHARACTERISTIC_IDENTITY: &str = "choice";
1013    /// `fiberType` -> `hopf_S3`
1014    pub const FIBER_TYPE: &str = "https://uor.foundation/convergence/hopf_S3";
1015    /// `levelName`
1016    pub const LEVEL_NAME: &str = "H";
1017}
1018
1019/// Level 3: O (octonions), dimension 8, self-reference.
1020pub mod l3_self {
1021    /// `algebraDimension`
1022    pub const ALGEBRA_DIMENSION: i64 = 8;
1023    /// `bettiSignature`
1024    pub const BETTI_SIGNATURE: &str = "[1,0,0,0,0,0,0,1]";
1025    /// `characteristicIdentity`
1026    pub const CHARACTERISTIC_IDENTITY: &str = "self-reference";
1027    /// `fiberType` -> `hopf_S7`
1028    pub const FIBER_TYPE: &str = "https://uor.foundation/convergence/hopf_S7";
1029    /// `levelName`
1030    pub const LEVEL_NAME: &str = "O";
1031}
1032
1033/// Hopf fiber S⁰: dimension 0, total space S¹, base pt.
1034pub mod hopf_s0 {
1035    /// `baseSpace`
1036    pub const BASE_SPACE: &str = "pt";
1037    /// `fiberDimension`
1038    pub const FIBER_DIMENSION: i64 = 0;
1039    /// `fiberSphere`
1040    pub const FIBER_SPHERE: &str = "S⁰";
1041    /// `totalSpace`
1042    pub const TOTAL_SPACE: &str = "S¹";
1043}
1044
1045/// Hopf fiber S¹: dimension 1, total space S³, base S².
1046pub mod hopf_s1 {
1047    /// `baseSpace`
1048    pub const BASE_SPACE: &str = "S²";
1049    /// `fiberDimension`
1050    pub const FIBER_DIMENSION: i64 = 1;
1051    /// `fiberSphere`
1052    pub const FIBER_SPHERE: &str = "S¹";
1053    /// `totalSpace`
1054    pub const TOTAL_SPACE: &str = "S³";
1055}
1056
1057/// Hopf fiber S³: dimension 3, total space S⁷, base S⁴.
1058pub mod hopf_s3 {
1059    /// `baseSpace`
1060    pub const BASE_SPACE: &str = "S⁴";
1061    /// `fiberDimension`
1062    pub const FIBER_DIMENSION: i64 = 3;
1063    /// `fiberSphere`
1064    pub const FIBER_SPHERE: &str = "S³";
1065    /// `totalSpace`
1066    pub const TOTAL_SPACE: &str = "S⁷";
1067}
1068
1069/// Hopf fiber S⁷: dimension 7, total space S¹⁵, base S⁸.
1070pub mod hopf_s7 {
1071    /// `baseSpace`
1072    pub const BASE_SPACE: &str = "S⁸";
1073    /// `fiberDimension`
1074    pub const FIBER_DIMENSION: i64 = 7;
1075    /// `fiberSphere`
1076    pub const FIBER_SPHERE: &str = "S⁷";
1077    /// `totalSpace`
1078    pub const TOTAL_SPACE: &str = "S¹⁵";
1079}