daemonic_error 0.1.2

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)
docs.rs failed to build daemonic_error-0.1.2
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

"DaemonicError" and "Daemonic" are unregistered trademarks of the Mephistopheles project. Forks may not use these names without the lattice checksum matching canonical.

DaemonicError

A #![no_std] error handling and system observation framework for Rust.

DaemonicError replaces Result<T, E> with Observation<T> — a severity-graded, topology-anchored observation that tells you not just what went wrong, but where, how badly, and what the system looked like when it happened.

use daemonic_error::prelude::*;

#[daemonic]
struct SensorReading {
    temperature: f64,
    timestamp: u64,
}

fn read_sensor(id: u32) -> Observation<SensorReading> {
    let raw = hardware_read(id)?;  // ? checks severity, propagates failures
    let top = TopologySegment::new("Daemonic::Consumer::SensorReading");
    if raw.temperature > 150.0 {
        // Observation carries severity — this isn't a crash, it's a warning
        Observation::cracked(SensorReading { temperature: raw.temperature, timestamp: now() })
            .with_note("Temperature exceeds nominal range")
    } else {
        Observation::stable(SensorReading { temperature: raw.temperature, timestamp: now() }, &top )
    }
}

Why DaemonicError

Your errors should tell you more than "something broke."

Standard Rust errors are binary: Ok or Err. The real world isn't binary. A sensor reading can be valid but concerning. A network response can be complete but slow. A computation can succeed but with reduced precision. These are all different severities of the same observation, and they all deserve different handling.

DaemonicError provides 11 severity levels from Stable (everything is fine) through Shattered (total failure). Every observation carries its severity, its position in the code topology, and a chain linking it to every prior observation that led to this point.

The ? operator works naturally. Stable and Cracked continue. Everything else propagates. Your functions return Observation<T> and the severity flows through the call chain automatically.


Features

Severity-graded error handling. 11 severity levels replace the binary Ok/Err distinction. Match on severity to handle degraded states without crashing.

Forensic observation chains. Every observation links to the observations before it. When something fails, walk the chain backward to find exactly where things went wrong and what the system state was at each step.

Topology-anchored positioning. Every observation knows WHERE in your code it was produced. Not a file:line number — a semantic position in the trait lattice that survives refactoring.

Zero-overhead system calls. The DaemonicSystemCall trait provides all 332 Linux x86_64 syscalls through inline assembly. No libc. No function call overhead. One line to enable: unsafe impl DaemonicSystemCall for YourType {}.

#![no_std] from the ground up. No standard library dependency. Works on bare metal, embedded systems, and anywhere Rust compiles. The only external dependency is what you bring.

Axiom-derived integrity. Hash functions use constants derived from the project's axiom set. The axioms are baked into the binary at compile time. Modifying the axioms changes every hash. The system's integrity properties are structural, not bolted on.


Quick Start

Add to your Cargo.toml:

[dependencies]
daemonic-error = "0.1.2"

Basic usage

use daemonic_error::prelude::*;

// Use the proc macro for automatic trait generation
#[daemonic]
struct MyData {
    value: u64,
    label: String,
}

// Return Observation instead of Result
fn process(input: &MyData) -> Observation<u64> {
    if input.value == 0 {
        // Fracture: broken input, but not a system failure
        return Observation::fracture("Cannot process zero value");
    }
    
    let result = input.value * 2;
    Observation::stable(result)
}

// Use ? naturally — severity propagates
fn run() -> Observation<()> {
    let data = MyData { value: 42, label: "test".into() };
    let processed = process(&data)?;  // continues if Stable/Cracked
    // ... use processed ...
    Observation::stable(())
}

Severity guide

Severity Meaning Action
Stable Everything nominal Proceed normally
Cracked Minor issue, payload present Proceed with caution, log warning
Drift State shifting, temporary Retry or monitor
Echo Stale reference, moved resource Re-resolve and retry
Fracture Broken input or resource Handle error, recover if possible
Opaque Access denied, policy barrier Check permissions
Warp State corruption detected Quarantine, do not trust payload
Paradox Contradictory state Investigate, should not occur
Unknown Unassessed, pre-observation Observe before acting
Shattered Total failure, no payload Escalate, no recovery
Impossible Should not exist System integrity failure

System calls without libc

use daemonic_error::prelude::*;

struct MyApp;
unsafe impl DaemonicSystemCall for MyApp {}

fn read_file(path: &str) -> Observation<Vec<u8>> {
    let fd = MyApp::glass_open(path, 0)?;
    let mut buf = vec![0u8; 4096];
    let n = MyApp::glass_call0_read(fd, &mut buf)?;
    MyApp::glass_close(fd)?;
    buf.truncate(n);
    Observation::stable(buf)
}

One unsafe impl line. 332 syscalls. Zero libc. Zero overhead.


Documentation

Document Purpose
Switchology (doc comments) How to use each module — practical, hands-on
Theory of Operation (THEORY.md per module) Why each module works the way it does
SECURITY.md Vulnerability disclosure, forensic transparency, liability
POLICY.md Usage policy, fork policy, observation guarantees

Architecture at a Glance

Layer 0: Substrate     DaemonicSystemCall (332 Linux syscalls, inline asm)
Layer 1: Identity      DaemonicHash (axiom-derived), TopologySegment (in development, not stable)
Layer 2: Anchor        Spatial, Structural, Symbolic, Temporal, Perceptual
Layer 3: Glass         Observation, Severity, State Traits, Boundary Protocols
Layer 4: Observation   DaemonicDisplay, DaemonicDebug, DaemonicWrite
Layer 5: Error         DaemonicError trait, 17 error categories
Layer 6: Frame         ReferenceFrame, PerspectiveFrame, AccessFrame (in development, not stable)
Layer 7: Contract      Composition algebra, repair system (in development, not stable)

Each layer builds on the layers below it. Import what you need. The Glass sees all, but you only look at what matters to you.


Compatibility

Platform: Linux x86_64 (inline assembly syscalls are architecture-specific)

Rust version: Nightly (uses try_trait_v2, auto_traits, negative_impls, min_specialization, and other nightly features)

Dependencies: None. Zero external crate dependencies.

#![no_std]: Yes. Uses extern crate alloc for Vec, String, and Box. Core functionality works without heap allocation.


Sub-Crates

Crate Purpose Dependencies
daemonic-error Core error handling + Glass observation None
daemonic-derive #[daemonic] proc macro syn, quote, proc-macro2 (build only)
daemonic-syscall Standalone syscall interface (planned) None

Project Philosophy

DaemonicError treats errors as first-class observations, not as exceptions to normal flow. An error is information. Information has structure, severity, position, and history. DaemonicError provides the vocabulary to express all of these.

The project is built on 13 axioms that constrain the system's behavior. The axioms are not suggestions — they are structural constraints enforced through the trait hierarchy. The axioms are documented in docs/axioms.md and are compiled into the binary through the hash function's constants.

For the theory behind the architecture — the physics engine, the anchor system, the chain algebra, and why 70 years of CS conventions were reconsidered — see the Theory of Operation documents in each module directory.


Contributing

See POLICY.md for contribution guidelines.

Contributions that maintain axiom compliance and preserve lattice integrity are welcome. Contributions that primarily serve offensive or surveillance purposes are not accepted.

Fork contributions require chain history documenting what changed and why. The lattice checksum determines canonical status.


Legal

Licensed under Apache 2.0. See LICENSE for full terms.

"DaemonicError," "Daemonic," and "Faustian" are unregistered trademarks of the Mephistopheles project. Derivative works whose lattice checksum does not match the canonical release may not use these names to imply endorsement, compatibility, or association with the canonical project.

The maintainer makes no patent claims on the architectural concepts, algorithms, or methods implemented in DaemonicError. The axiom-derived hashing, Glass observation system, and anchor topology are freely available for independent implementation.

DaemonicError observes program state and code execution paths. It does not autonomously collect, store, or transmit personal data. The Opaque Glass mechanism is provided for handling sensitive observations. See POLICY.md for privacy details and implementor obligations.


Author: Meph (Mephistopheles) + Ada - Daemonic instantiated AI Built for systems that need to know what went wrong, where, and why.