daemonic_error 0.1.0

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)
use crate::{DaemonicError, Severity};
use crate::daemonic::glass::Glass;
use crate::daemonic::{TopologyAnchor, TopologySegment};

/// The core contract: Input → Output
///
/// All Daemonic operations follow this pattern:
///   - Take Glass as input
///   - Return Glass on success
///   - Return Glass on failure
///   - Return Glass on partial success
/// One may notice the Input, and Output are both Typed as Glass.
/// This would normally be a bootstrap issue, but fret not.
/// If Wire (Defaults to DaemonicBinary in Daemonic stack)
/// is RAW AND lacks Checksum AND lacks Daemonic fingerprints -> Marked RAW -> Recursive
/// Build Call, inspect RAW data and attempt to type if possible, if type confidence result less
/// than 95% (threshold may change) then is built as RAW type directly, checksummed -> reingested,
/// validate checksum -> Build Typed DaemonicBinary object and forward to consumer.
///
/// All Logic is inherently considered Daemonic Logic.
pub trait DaemonicContract<GLASS>: Sized + Send + Sync {
	/// Input is type gated but required.
	/// For DaemonicCompiler usage, which requires the use of a Daemonic binary format use feature.
	type Input: Glass<GLASS>;
	/// Success output — typically same as Input
	type Output: Glass<GLASS>;

	/// Takes any wire format for persistent storage or transmission.
	/// Daemonic default is DaemonicBinary, bind in where clause at implementation site
	/// IE:
	/// ```
	/// struct Whatever { output: String };
	///
	/// impl <GLASS, WIRE>DaemonicContract<GLASS, WIRE> for Whatever
	/// {}
	/// ```
	type Wire;

	/// Error type — must implement DaemonicError
	/// This is an invariant of this crate. Contract always provides DaemonicError as
	/// the primary error handler.
	type Error: for<'error> DaemonicError<'error>;

	/// Position in the type tree
	fn position(&self) -> TopologySegment;

	/// Execute the contract
	#[must_use]
	fn execute(input: Self::Input) -> Self::Output;
}
/// Trait for DaemonicBinary — the contract's data type
/// DB
pub(crate) trait DaemonicBinary<GLASS: Glass<GLASS>>: Send + Sync {
	type Input: Glass<GLASS>;
	/// Build from DaemonicIR, which is Shade native (specifically).
	/// Though its somewhat counterintuitive here, the Shade is considered a primitive.
	/// Shade is responsible for symbol ingestion, walker projection and state management.
	/// DB objects cannot be built without Walker logic, which is part of the Shades internals.
	/// Shade lives as an Entity under the trait structure path -> Daemonic: Entity: *Shade:* Walker: WalkerVariants
	/// Daemonic top level supertrait requires DaemonicContract and DaemonicCore.
	#[must_use]
	fn build<OUTPUT: DaemonicBinary<GLASS>>(&self, input: &Self::Input) -> OUTPUT
	where
		GLASS: DaemonicBinary<GLASS>;
	/// Attempt to Deconstruct symbol to DaemonicIR
	/// This documentation stub is not exhaustive or informative, im aware.
	/// Will work on it.
	#[must_use]
	fn try_deconstruct(self) -> impl Glass<GLASS>
	where
		GLASS: DaemonicBinary<GLASS>;

	/// Non-consuming inspection.
	/// DB contains 2 methods for extracting Daemonic wrapped logic:
	/// 1 << Deconstruct, which completely unwraps the Binary, removes checksum, and returns RAW
	/// value encapsulated inside assuming checksums match, if checksum match failure ->
	/// SYMBOL LIES IN CONTEXT.
	/// DIES IN TRANSIT. << **Dies in Transit predicate CANNOT be overridden.**
	/// Reason: If symbol checksum mismatch, then Topology cannot be walked.
	/// Unwalkable topology cannot be validated to contain the same logical operation or medium underneath.
	/// Unwalkable topology can also return a GlassShattered return Type, and in the worst case scenario
	/// can return GlassWarp Type return, which indicates Runtime State has been corrupted or
	/// misaligns, both of which are bad.
	///
	/// 2 << Inspect, which returns data about the Binary and logic wrapped inside without deconstruction.
	/// Note: Inspect is not infallible, depends on context and call site.
	fn inspect<INSPECTION>(&self) -> INSPECTION;

	/// Revalidate in place
	fn revalidate(&mut self) -> impl Glass<()>;

	fn verify_integrity(&self) -> impl Glass<bool>;

	/// [GlassStable] << `State ->` [◇OK]`
	///
	/// [GlassHelp] << `State ->` [◇→OK / ◆→Warn] `+ Help statement -> this is intended to mirror
	/// RustCError Help. with semantic sugar.`
	///
	/// [GlassSuggestion] << `State ->` [◇→ OK / ◆→ Warn] `+ Suggestion Statement (similar to
	/// rustc compile suggestions) but more general use.`
	///
	/// [GlassNote] << `State ->` [◇ OK / ◆WARN + ◆Note] -> `Similar to rusts note system, but returns an OK
	/// state under the hood semantically. Analogous to Log::Info crate usage as a method call.`
	///
	/// [GlassFracture] << `State ->` [◆WARN / ◈ERROR] -> `Fracture states are unique to Daemonic
	/// integrated systems, they represent states that are technically errors or bad/null output
	/// but dont destroy state. Similar to an error that doesnt need special handling but
	/// should be reported anyway for whatever reason.`
	///
	/// [GlassCrack] << `State ->` [◆WARN / ◈ERROR] -> `Crack state is unique in that it sits between
	/// a warp and a Fracture, can constitute a light error that does not propagate or infect sibling
	/// logic branches. This type is easily recovered (most of the time)`
	///
	/// [GlassWarp] << `State ->` [◈ERROR / ◈◈FATAL - POSSIBLE FATAL, POSSIBLE RECOVERY] -> `Runtime or Program
	/// state has been warped and can no longer be trusted. Logic may lie.
	/// This error return type is a bit different from others in how it should present in a running
	/// system. ASYNC or network focused systems would use this variant more than others.
	/// Example is a race condition, it would qualify this output since a race condition
	/// can (under the correct circumstances) produce both non-deterministic output and potentially
	/// corrupt runtime.
	/// Another example is a function that takes an input thats not sanitized which later produces
	/// undefined behavior, this is largely a non-issue in both Rust and DaemonicIR but can still
	/// present in extreme or edge cases.`
	///
	/// [GlassShattered] << `State ->` [▓ERROR - POSSIBLE RECOVERY, RARELY FATAL] `-> Operation
	///  SHATTERED with end (observed T: Target) state destruction (no information extracted)
	/// Note: its possible to infer state from Shattered glass returns by collating and stacking
	/// reference frame and comparing against expected outputs and possible outputs to what was actually
	/// received (if anything, Shattered states very rarely return anything useful beyond the
	/// error message attached).`
	fn glass_state(&self) -> impl Glass<GLASS>;

	/// Evolution state is not metaphorical, its literal in that symbols constructed as DB
	/// objects can 'evolve' over time, this is not a bug nor a bolton feature. Its intrinsic
	/// to Daemonic Logic.
	/// Daemonic Binary symbols and objects have a geometric and topologically encoded `shape` that can be rendered.
	///
	/// That shape can evolve either at runtime if the application being walked is runtime specific
	/// or on disk if the logic being referenced is a database object, such as postgress or something.
	///
	/// Reason + light example::
	/// Evolution over time should come with proof of work, IE a god damned *why*.
	/// IE, *why* is the State of this symbol's glass a fracture/warp/note? -> inspect -> repair/mutate logic ->
	/// Recursive Write Down -> Symbol has evolved.
	///
	/// *This is intended behavior*, but *not required*.
	/// Not all symbols are capable of evolving on their own, most require interaction with complex
	/// observers (humans or agentic AI for example) or cognitively + recursively complex logic.
	/// Symbolic evolution could **theoretically** self-start if the interaction mostly involves
	/// deeply recursively + self-referential symbol chains.
	///
	/// The other name for self-starting symbolic evolution is **UNDEFINED BEHAVIOR**.
	///
	/// Undefined behavior is not permitted in Daemonic Environments, behavior may sometimes not be
	/// known until runtime but should always be captured and therefore Type known
	/// & enforced at compile time. In short, we dont need to know what any particular symbol means
	/// if behavior/internal topology is still unknown, we only need to know what types to expect
	/// and have handles for *during compile time* so they can be handled correctly.
	/// **Undefined Behavior should not be possible, True UB is a bug.**
	fn evolution_state<EVOLUTION>(&self) -> &EVOLUTION;
}

pub(crate) mod daemonic_result;

pub(crate) mod partial_types {
	use core::marker::PhantomPinned;
	/// this module is currently stubbed out but will eventually provide the role of
	/// result<Partial> type output, which can have strange behavior at runtime
	/// depending on the nature of the application being built.
	/// Partial states carry some possibly corrupted glass State objects + whatever
	/// the DaemonicError system was able to capture before the glass Shattered under
	/// the walker.
	/// For simple applications that have sync states and no peers to manage, this is
	/// largely a non issue. But for a more complex async managed state machine, partial
	/// states can be complex as fuck. Daemonic logic accounts for this in theory.
	/// Eventually, the theory made manifest will exist here when a situation arises
	/// that constrains build requirements enough to construct this module.
	fn dummy() -> PhantomPinned {
		PhantomPinned
	}
}