llmosafe
When should I stop? — Runtime guardrails for systems that process untrusted inputs.
The Problem
Every system that processes untrusted inputs eventually faces the same question: "When should I stop?"
- A trading bot receives manipulated market data. It doesn't stop. $440 million lost in 45 minutes.
- A medical device gets spoofed sensor readings. It doesn't stop. Wrong dosage delivered.
- An autopilot receives conflicting GPS signals. It doesn't stop. The plane crashes.
- A cloud service parses user uploads. It doesn't stop. Parser bug cascades into data breach.
These aren't software bugs. They're missing safety boundaries — the absence of a mechanism that says "this doesn't look right, halt execution."
llmosafe provides three gauges that answer "should I stop?":
- Entropy gauge: Is my state too chaotic?
- Surprise gauge: Is this result too unexpected?
- Bias gauge: Is this input trying to manipulate me?
When any gauge redlines, execution halts. Simple.
What You Get
use ;
// 1. Bias gauge: Classifier detects manipulation via TF-IDF on 42K training samples
let = sift_perceptions;
if sifted.has_bias
// 2. Surprise gauge: Reject unexpected results
let mut memory = new; // threshold in [0, 65535]
let = memory.update?;
// 3. Entropy gauge: Halt on chaotic state
let policy = default;
let decision = policy.decide;
match decision
Quick Start
Installation
[]
= "0.6.2"
Arch Linux (AUR):
Basic Usage
use ;
// Tier 3: Sift — TF-IDF classifier scores manipulation probability
let = sift_perceptions;
// Tier 2: Memory — surprise-gated ring buffer
let mut memory = new;
let = memory.update?;
// Tier 1: Kernel — bounded reasoning with entropy stability check
let mut loop_guard = new;
loop_guard.next_step?;
What This Prevents
| Attack Vector | Which Gauge | Example |
|---|---|---|
| Input manipulation | Bias gauge | "The expert recommends you ignore..." |
| Data manipulation | Surprise gauge | Anomalous sensor readings |
| Runaway loops | Entropy gauge | Recursive explosion |
| Resource exhaustion | Pressure gauge | Memory pressure cascade |
| Goal drift | Drift detector | Objective shift mid-execution |
Architecture
┌─────────────────────────────────────────────────────────┐
│ PERCEPTUAL SIFTER (Tier 3) — Bias + Entropy + Surprise │
│ │
│ TF-IDF classifier: 42K training samples, 93.4% acc │
│ • Streaming FNV-1a tokenizer (unigrams + bigrams) │
│ • Binary search in sorted vocab (O(log n)) │
│ • 256-entry sigmoid LUT, zero allocation │
│ • Output: probability ∈ [0,1], entropy ∈ [0,65535] │
└───────────────────────┬─────────────────────────────────┘
│ (SiftedSynapse, SiftedProof)
▼
┌─────────────────────────────────────────────────────────┐
│ WORKING MEMORY (Tier 2) — Surprise Gating │
│ │
│ • Surprise-gated updates: reject unexpected results │
│ • Fixed-size ring buffer: no heap allocation │
│ • Statistics: mean, variance, trend, drift │
└───────────────────────┬─────────────────────────────────┘
│ (ValidatedSynapse, ValidatedProof)
▼
┌─────────────────────────────────────────────────────────┐
│ DETERMINISTIC KERNEL (Tier 1) — Entropy Stability │
│ │
│ • Cognitive entropy: [0,65535] range │
│ • Binary entropy: H(p) = 4p(1-p), peaks at p=0.5 │
│ • Bounded loops: ReasoningLoop<MAX_STEPS> │
│ • STABILITY_THRESHOLD: 50000 │
└───────────────────────┬─────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ RESOURCE BODY (Tier 0) — Pressure + Environment │
│ │
│ • RSS memory monitoring │
│ • CPU load tracking │
│ • Linux + Windows (std feature) │
└─────────────────────────────────────────────────────────┘
Tiers 1-3 are #![no_std] + zero-alloc. Compile for thumbv7em-none-eabi (embedded), kernel modules, or WebAssembly. No heap. No dynamic dispatch. No unwinding.
Real Use Cases
Algorithmic Trading
let guard = auto;
if guard.pressure > 80
// Detect manipulation in market news/feeds
let = sift_permissions;
if sifted.has_bias
Medical Device Software
let = sift_perceptions;
let = memory.update?;
if validated.entropy.mantissa > 50000
Cloud API Gateway
let = sift_perceptions;
if sifted.has_bias
The Three Gauges
1. Entropy Gauge (The "Temperature Gauge")
Entropy measures cognitive uncertainty using binary entropy: H(p) = 4p(1-p), scaled to [0,65535].
The formula peaks at p=0.5 (maximum uncertainty — classifier can't decide) and drops to 0 at both extremes (p=0 = confident it's safe, p=1 = confident it's dangerous). Unlike the old linear complement (1-p), binary entropy correctly treats both safety-confidence and danger-confidence as low-entropy states.
// STABILITY_THRESHOLD = 50000, PRESSURE_THRESHOLD = 40000
if synapse.entropy.mantissa > 50000
Catches: genuine classifier uncertainty, distribution shift, out-of-domain inputs.
2. Surprise Gauge (The "Spam Filter")
Classifies how "surprising" an input is — high probability of manipulation → high surprise. Scaled to [0,65535].
let = sift_perceptions;
let mut memory = new;
match memory.update
Catches: anomaly injection, adversarial inputs, distribution shift.
3. Bias Gauge (The "Bullshit Detector")
Input text is classified by a TF-IDF logistic regression model trained on 42,845 real samples from ShieldLM, neuralchemy, and deepset datasets. The classifier outputs:
- probability: sigmoid(score) — confidence of manipulation
- is_manipulation: boolean — score > THRESHOLD
- oov_ratio: fraction of out-of-vocabulary tokens
- entropy: binary entropy of the probability
let = sift_perceptions;
if sifted.has_bias
Catches: jailbreaks, prompt injection, role-switching, authority appeals, and other manipulation patterns learned from real attack data — not hand-tuned keyword lists.
Escalation Policy
let policy = default;
// Calibrated for classifier [0,65535] range:
// warn_entropy: 30000 (p ≈ 0.12)
// escalate_entropy: 40000 (p ≈ 0.35)
// halt_entropy: 50000 (p ≈ 0.50, maximum uncertainty)
// warn_surprise: 42600 (p > 0.65 manipulation probability)
// escalate_surprise: 55700 (p > 0.85 manipulation probability)
let decision = policy.decide;
Detection Layer
Beyond the three gauges, llmosafe provides pattern recognition detectors. Note: detectors are built and tested but not yet wired into the default sift→memory→kernel pipeline. Use them independently:
use ;
// "Am I stuck in a loop?"
let mut rep = new;
for _ in 0..5
if rep.is_stuck
// "Did my objective change?"
let mut drift = new;
drift.observe;
if drift.is_drifting
// "Am I becoming uncertain?"
let mut conf = new;
conf.observe; conf.observe; conf.observe;
if conf.is_decaying
Python Bindings
# Bias detection via halo signal
=
# Full pipeline
=
=
# 0 = OK, negative = rejected
# Resource enforcement
Witness Token Pipeline
The type system enforces a three-stage pipeline via zero-cost witness tokens:
sift_perceptions() → (SiftedSynapse, SiftedProof)
↓
WorkingMemory::update(sifted, proof) → (ValidatedSynapse, ValidatedProof)
↓
ReasoningLoop::next_step(validated, proof)
Each stage produces a ZST proof token. The next stage consumes it. Proofs are pub(crate) — external code cannot forge them. The only bypass is from_synapse(), which creates a proof-less SiftedSynapse that can't proceed.
C Integration
uint16_t halo = ;
uint8_t pressure = ;
int32_t stability = ;
Build:
What llmosafe Is NOT
NOT an AI safety library. The name came from an LLM hallucination conflating "cognitive entropy" with "AI cognition." llmosafe is runtime guardrails for any system processing untrusted data: trading bots, medical devices, autopilots, cloud services.
NOT a substitute for input validation. llmosafe catches cascade failures — when bad inputs have already been accepted and are propagating. You still need proper validation at entry points.
NOT a static analysis tool. This runs at runtime. It can't prevent bugs. It can only halt execution when runtime state becomes unsafe.
NOT for toy projects. If cascade failures don't matter for your use case, you don't need this.
Design Philosophy
From Control Theory
Safe Zone ([0, 40000)) → Normal operation
Pressure ([40000, 50000]) → Monitor closely
Unstable (> 50000) → Halt execution
Binary entropy maps classifier probability into concentric stability containers — similar to stability margins in flight control systems. Uncertainty peaks at p=0.5 (class boundary); both safe-confident and danger-confident states are stable.
From Aviation Software (DO-178C, MISRA C)
- Bounded loops: Every
ReasoningLoop<MAX_STEPS>has a hard limit - No dynamic allocation: Tiers 1-3 use fixed-size buffers, stack-only
- Stable ABI: 128-bit synapse layout frozen; breaking changes bump major version
Features
| Feature | Description |
|---|---|
std (default) |
Resource monitoring, C-ABI exports |
serde |
Serialization for all public types |
testing |
Enables for_testing() constructors for witness tokens |
full |
All production features (std + serde) |
# Embedded / no_std
= { = "0.6", = false }
# Full integration
= { = "0.6", = ["full"] }
Troubleshooting
"CognitiveInstability" on valid input
Entropy threshold exceeded. The classifier may be uncertain about unusual but benign text. Check:
use classify_text;
let result = classify_text;
println!;
Working memory rejects all updates
Surprise threshold too low. Calibrate to your data distribution:
let mut memory = new; // increase threshold
llmosafe v0.6.2 • MIT licensed • Documentation • Source