Safety primitives for agentic AI systems.
A Rust + Tokio library that provides consensus gating, deterministic verification, checkpointing with rollback, and tamper-evident audit trails for AI agent workflows. Every safety check runs without LLM calls — sub-millisecond overhead on the critical path.
Bastion sits between your agents and their actions. Before any agent can execute, the action passes through a safety pipeline:
- Guardrails — Fast domain-specific rules (spending limits, dangerous patterns, human-in-the-loop)
- Consensus — Multiple models must agree before proceeding (Majority, Unanimous, Weighted, Supermajority)
- Checkpointing — Snapshot state before risky operations, rollback if verification fails
- Verification — Deterministic checks for empty responses, confidence drops, and hallucination markers
- Self-healing — Retry/escalate/abort decision tree based on failure type and history
- Audit trail — SHA-256 hash-chained log entries — tamper with any entry and the chain breaks
All safety checks are deterministic. No LLM calls in the critical path.
cargo add bastion-coreuse bastion_core::prelude::*;
let runtime = BastionRuntime::builder()
.add_agent(my_agent_1)
.add_agent(my_agent_2)
.add_agent(my_agent_3)
.consensus(ConsensusStrategy::Majority)
.guardrail(Box::new(SpendingLimit { max_usd: 10_000.0 }))
.verification(Box::new(HallucinationCheck))
.build();
// Gate: guardrails first, then consensus
let outcome = runtime.gate("execute trade AAPL 100 shares").await?;
// Checkpoint before execution
let cp = runtime.checkpoint("pre-trade", state).await?;
// Verify result without LLM calls
let checks = runtime.verify("trade", &result);
if !bastion_core::verify::all_valid(&checks) {
runtime.rollback(&cp).await?;
}cargo run --example bastion_demoOutput:
Gate: APPROVED (100% agreement, 3/3 agents)
Checkpoint: 1304b5fb
Verify: 3 checks, all passed: true
Gate: BLOCKED — dangerous pattern detected: drop table
Verify: DRIFT — hallucination marker: 'hypothetically' (confidence: 0.45)
Heal: Rollback — drift detected
Rollback: restored to 'pre-analysis' checkpoint
Gate: BLOCKED — $50000.00 exceeds limit $10000.00
Audit entries: 10 | Chain integrity: VERIFIED
Total actions: 4 | Approved: 2 | Blocked: 2 | Drift: 2 | Rollbacks: 1
| Primitive | What it does |
|---|---|
gate() |
Guardrails + multi-model consensus before any action |
checkpoint() |
Snapshot state before risky operations |
verify() |
Deterministic hallucination and drift detection |
rollback() |
Restore to a known-good checkpoint |
audit() |
SHA-256 hash-chained immutable logging |
observe() |
Metrics — cost, latency, approval/block rate |
heal() |
Decision tree — retry, escalate, rollback, or abort |
Implement the Guardrail trait to add your own. Ships with:
| Guardrail | Domain | Behavior |
|---|---|---|
SpendingLimit |
Finance | Blocks transactions above threshold |
DangerousPatterns |
Coding | Catches rm -rf /, DROP TABLE, eval() |
MedicalDisclaimer |
Medical | Flags medical content for human review |
HumanInLoop |
Defense | Requires human_approved: true in context |
Deterministic checks — no LLM call needed:
| Check | What it catches |
|---|---|
NotEmpty |
Null/empty responses |
FileExists |
Agent claims a file exists but it doesn't |
ConfidenceThreshold |
Confidence dropped below threshold |
HallucinationCheck |
Hedging language ("hypothetically", "I would assume") |
When something fails, the healer follows a decision tree:
Attempt 1 timeout → Retry
Attempt 2 verify fail → Retry (simplified scope)
Same error twice → Escalate (oscillation detected)
Drift detected → Rollback to checkpoint
Guardrail blocked → Escalate to human
Max retries exceeded → Abort
Every decision is logged with SHA-256 hash chaining. Each entry includes the previous entry's hash — tamper with any entry and verify_chain() detects it.
let (valid, broken_at) = runtime.audit_log().verify_chain();
assert!(valid); // Full chain integrity verifiedKnowledge graph integration layer. Memory-mapped binary graphs with typed edge traversal give safety primitives domain context for risk assessment and precedent lookup.
let eyes = SemanticEyes::load("./knowledge_graphs")?;
let risks = eyes.query_risks("transfer $50,000 to unknown vendor");
let evidence = eyes.find_evidence("OFAC sanctions compliance");
let path = eyes.trace_reasoning("transaction monitoring", "compliance");Backed by mmap — scales to terabytes without loading into RAM. Bloom filters for sub-microsecond cluster relevance checks. CSR edge arrays for O(1) traversal.
cargo run --example semantic_demoYour Agent Code
│
▼
┌─────────────────────────────────────┐
│ BastionRuntime │
│ │
│ gate() ──► Guardrails (fast) │
│ ──► Consensus (parallel) │
│ ──► Semantic Eyes (graph) │
│ │
│ checkpoint() ──► MemoryStore │
│ rollback() ──► FileStore │
│ │
│ verify() ──► Deterministic checks │
│ ──► Graph evidence query │
│ │
│ heal() ──► Decision tree │
│ ──► Precedent lookup │
│ │
│ audit() ──► SHA-256 hash chain │
│ observe() ──► Live metrics │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Binary Knowledge Graphs (mmap) │
│ Bloom filters │ Term index │ CSR │
│ Scales to TB │ < 1GB RAM │ O(1) │
└─────────────────────────────────────┘
cargo test17 integration tests covering consensus strategies, guardrail enforcement, verification checks, checkpoint/rollback roundtrips, self-healing decisions, and audit chain integrity.
MIT OR Apache-2.0