daemonic_error 0.1.1

Errors that compose, predict, and leave receipts - Compose: algebraic combination (in active development) - Predict: Glass/Severity - Receipts: audit trail, position, checksum - Reflection: Runtime Reflection through TopologySegment (in active development)
// ═══════════════════════════════════════════════════════════════
// SECTION 2: FRAME SUBTRAIT HIERARCHY
// ═══════════════════════════════════════════════════════════════
//
// "Frame" currently means 4 different things. Each gets its
// own trait so they're distinguishable in type signatures.
//
// Frame is a subtrait of Glass — every frame IS observable
// through Glass. But not every Glass observation is a frame.
// Frames are the CONTEXT in which observations are made.


/// The general Frame interface.
/// A frame is a reference configuration for interpreting observations.
/// Frames determine HOW observations are interpreted, not WHAT is observed.
pub trait Frame: Anchor {
	/// What type of frame is this?
	fn frame_type(&self) -> FrameType;

	/// Is this frame compatible with another frame?
	/// Two frames are compatible if observations made in one
	/// can be meaningfully compared to observations in the other.
	fn is_compatible_with(&self, other: &dyn Frame) -> bool {
		// Default: same frame type = compatible
		self.frame_type() == other.frame_type()
	}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FrameType {
	Reference,
	Perspective,
	Access,
	Execution,
	Ambiguous,
}

/// Physics reference frame — coordinate system for measurement.
/// Defined by position + orientation + scale.
/// Axiom 4 applies: no ReferenceFrame is privileged.
pub trait ReferenceFrame: Frame
where
	Self: ?Sized,
{
	/// Origin position of this frame
	fn origin(&self) -> &TopologySegment;

	/// Transform an observation from this frame to another.
	/// Returns None if transformation is impossible (incompatible frames).
	fn transform_to<GLASS>(
		&self,
		observation: &impl Glass<GLASS>,
		target_frame: &dyn ReferenceFrame,
	) -> Option<Observation<GLASS>>
	where
		GLASS: Clone,
		Self: Sized;
}

impl Frame for ! {
	fn frame_type(&self) -> FrameType {
		todo!()
	}
}

impl Anchor for ! {
	fn anchor_domains(&self) -> AnchorDomainSet {
		todo!()
	}
}

impl ReferenceFrame for ! {
	fn origin(&self) -> &TopologySegment {
		todo!()
	}

	fn transform_to<GLASS>(&self, observation: &impl Glass<GLASS>, target_frame: &dyn ReferenceFrame) -> Option<Observation<GLASS>>
	where
		GLASS: Clone,
		Self: Sized
	{
		todo!()
	}
}
impl Frame for () {
	fn frame_type(&self) -> FrameType {
		todo!()
	}
}

impl Anchor for () {
	fn anchor_domains(&self) -> AnchorDomainSet {
		todo!()
	}
}

impl ReferenceFrame for () {
	fn origin(&self) -> &TopologySegment {
		todo!()
	}

	fn transform_to<GLASS>(&self, observation: &impl Glass<GLASS>, target_frame: &dyn ReferenceFrame) -> Option<Observation<GLASS>>
	where
		GLASS: Clone,
		Self: Sized
	{
		todo!()
	}
}

/// Interpretive perspective — the observer's angle of approach.
/// Shaped by templates, position, and accumulated experience.
/// Different perspectives on the same phenomenon produce
/// different observations, all equally valid (Axiom 4).
pub trait PerspectiveFrame: Frame {
	/// What templates/experience shape this perspective?
	fn perspective_basis(&self) -> &str;

	/// How much does this perspective bias observations?
	/// 0.0 = perfectly neutral (impossible in practice)
	/// 1.0 = completely biased (only sees what it expects)
	fn bias_estimate(&self) -> f64 { 0.5 }
}

/// Access control frame — determines who can see through
/// which Glass observations. The Black Glass Protocol operates
/// at this level.
///
/// AccessFrames ARE deliberately privileged (Axiom 4 does NOT
/// apply here). Some positions can see. Others can't.
/// That's the point of access control.
pub trait AccessFrame: Frame {
	/// Positions authorized to observe through this frame
	fn authorized_positions(&self) -> &[TopologySegment];

	/// Can the given position observe through this frame?
	fn can_observe(&self, observer_position: &TopologySegment) -> bool {
		todo!("This needs to be fixed, but isnt version 7 blocking so fuck it, added to the list of shit to do")
		// self.authorized_positions().iter().any(|auth| {
		// 	observer_position.label.as_str().starts_with(
		// 		&auth.segments().label.payload().iter().map(|s| *s).collect::<Vec<_>>()
		// 	)
		// })
	}
}

/// Computational execution frame — stack context for logic.
/// Contains scope, local variables, and execution state.
/// The runtime analog of what a stack frame is in Rust.
pub trait ExecutionFrame: Frame {
	/// Scope of this execution frame
	fn scope_depth(&self) -> usize;

	/// Is this frame currently active (on the call stack)?
	fn is_active(&self) -> bool;

	/// Parent frame (caller), if any
	fn parent_frame_id(&self) -> Option<u64>;
}

use alloc::vec::Vec;
use crate::daemonic::{AnchorDomainSet, TopologyAnchor, TopologySegment};
use crate::Severity;
use crate::Glass;
use crate::Observation;
use crate::daemonic::{Anchor, SpatialAnchor};