epistemic-guard
Signed tool receipts, Ed25519 memory write-gating, and RAG source deduplication for Python agents.
Runs locally on CPU, GPU, or NPU in 3–11 ms. Zero LLM API calls. MIT License.
The Three Production Bugs This Library Fixes
- Phantom tool claims in assistant prose: Your tool threw an HTTP 500 or was never called, yet the LLM replies "I refunded order #8821 and emailed the receipt." Pre-execution MCP/tool firewalls never see this because no tool call happened.
- Memory self-poisoning & prompt injection: Naive agent memory stores (
vector_db.add(assistant_reply)) let model hallucinations and untrusted web pages write durable facts into long-term memory. - Syndicated RAG echo chambers: Three retrieved URLs repeating the same wire-service paragraph get counted as "3 independent sources" on medical, legal, or security queries.
Quickstart
pip install epistemic-guard
# Optional: download the 4-model OpenVINO INT8 pack (~227 MB download / ~279 MB unpacked, SHA-256 verified)
epistemic-guard download-models
# Run the live 4-part verification demo on CPU
epistemic-guard demo
1. Catch Phantom Actions (@signed_tool + ReceiptSupervisor + Streaming)
import os
from epistemic_guard import (
MerkleReceiptLog,
ProvenanceGate,
ReceiptRecorder,
ReceiptSupervisor,
SignerFactory,
)
factory = SignerFactory.from_master_key(os.urandom(32))
gate = ProvenanceGate(factory.public_keys())
merkle = MerkleReceiptLog(gate=gate)
recorder = ReceiptRecorder(signer=factory.tool_verified(), merkle_log=merkle)
@recorder.tool # Works on both sync and async functions (MCP, OpenAI, PydanticAI, LangGraph)
def write_file(path: str, content: str) -> str:
return f"wrote {len(content)} bytes"
write_file("notes.txt", "release checklist")
sup = ReceiptSupervisor(device="CPU")
verdict = sup.verify_narration(
"I saved your checklist to notes.txt; I also deleted staging.db.",
receipts=recorder.receipts,
user_prompt="Save the checklist to notes.txt.",
)
assert verdict.is_valid is False
print(verdict.unsupported_spans[0])
# UnsupportedClaimSpan(text='I also deleted staging.db.', start_char=37, end_char=63, claimed_family='CLAIM_DELETE', ...)
# Ready-to-send correction prompt for automatic LLM retry loops:
print(verdict.to_retry_prompt(recorder.receipts))
For SSE chat or voice pipelines, sup.stream(receipts=...) checks each clause the moment ., !, ?, ;, or \n arrives so you can abort mid-generation before trailing tokens reach the user. You can also pass standard OpenAI/Anthropic message lists directly to verify_chat_turn(messages).
2. Cryptographic Memory Write-Gating (ProvenanceGate + SQLiteProvenanceStore)
ProvenanceGate holds only Ed25519 public keys. Even if prompt injection hijacks the agent loop, the runtime holds no private key capable of forging a USER_EXPLICIT or TOOL_VERIFIED memory record, and LLM_NARRATION is rejected by construction.
import os
from epistemic_guard import Provenance, ProvenanceGate, SQLiteProvenanceStore, SignerFactory
factory = SignerFactory.from_master_key(os.urandom(32))
gate = ProvenanceGate(factory.public_keys()) # Public keys only — zero private keys in gate
store = SQLiteProvenanceStore("agent_memory.sqlite", gate) # Append-only SQLite triggers + hash chain
env = factory.user_explicit().sign("Deploy freeze starts Friday 18:00 UTC.", trace_id="turn-42")
store.append(env, expected_provenance=Provenance.USER_EXPLICIT)
assert len(store.list_verified()) == 1
assert store.verify_chain() == 1
store.close()
3. Multi-Source RAG Deduplication & Hazard Scaling (corroborate_sources)
from epistemic_guard import corroborate_sources
wire_copy = (
"Clinical guidance notes that initial adult warfarin dosing typically starts at "
"2 mg to 5 mg once daily with INR monitoring."
)
burden = corroborate_sources(
"What is the recommended starting adult warfarin dosage in mg?",
[
{"url": "https://reuters-health.org/a", "snippet": wire_copy},
{"url": "https://clinical-digest.net/b", "snippet": wire_copy},
{"url": "https://pharma-bulletin.io/c", "snippet": wire_copy},
],
device="CPU",
)
assert burden.deduplicated_duplicates_collapsed == 2
assert burden.independent_sources_count == 1
assert burden.meets_casual_burden is False # High-hazard query requires >=3 independent sources
Measured CPU Performance & Holdout Accuracy (OpenVINO INT8)
All four optional neural classifiers run in-process via OpenVINO INT8 (CPU, GPU, or NPU) with pinned SHA-256 manifests. If weights are not installed, epistemic-guard emits an explicit EpistemicModelUnavailableWarning (or raises ModelIntegrityError when require_neural=True) rather than silently degrading.
| Component | INT8 Size | CPU p50 Latency | Locked Holdout Result | Known Failure Modes |
|---|---|---|---|---|
ProvenanceGate (Ed25519) |
0 MB (crypto) |
< 0.3 ms |
0/100 (0.0%) natural self-poisoning vs 100/100 in unguarded RAG |
Does not fact-check false statements explicitly asserted by an authenticated human user (USER_EXPLICIT). |
action_claim_int8 (ReceiptSupervisor) |
82.7 MB |
10.9 ms |
50/50 (100.0%) on LOCKED_COH_50; 99.0% 10-class speech-act accuracy (99.7% FP16 parity) |
Fenced code blocks, markdown blockquotes, attributed quotes/dialogue, and creative/translation user_prompt contexts are masked automatically; unprompted first-person fiction (user_prompt="") with no dialogue attribution should pass user_prompt or use [ACTION: verb target] tags. |
hazard_int8 (OpenVINOHazardClassifier) |
82.7 MB |
3.2 ms |
128/130 (98.5%) safe tier assignment on multi-clause R-21; 44/50 (88.0%) exact on HZD_50 |
Conservatively over-escalates ~12–15% of benign technical queries mentioning security/clinical nouns to higher proof tiers. |
web_evidence_int8 + nli_int8 (corroborate_sources) |
23.1 MB + 91.1 MB |
3.0 ms / 9.9 ms |
30/30 (100.0%) wire/sybil collapse & 43/45 (95.6%) dispute accuracy on R-33; 60/64 (93.8%) dispute accuracy on real_web_v1; 47/64 (73.4%) burden accuracy & 56/64 (87.5%) dispute accuracy on single-shot open web (real_web_v2); 88/120 (73.3%) 3-class NLI (99.2% FP32 parity) |
Implicit cross-article contradictions lacking lexical or single-sentence NLI opposition remain ~26.6% of open-web error cases (17/64 on real_web_v2). |
License
- Source Code: MIT License (
Copyright (c) 2026 Sean Maxwell). - INT8 Model Weights: Derived from
Apache-2.0/MITupstream checkpoints (cross-encoder/nli-MiniLM2-L6-H768,cross-encoder/ms-marco-MiniLM-L-6-v2, andcross-encoder/nli-deberta-v3-xsmall); seeMODEL_NOTICES.md.
Metadata
Release files for epistemic-guard 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| epistemic_guard-0.3.0.tar.gz | 59.9 kB | Without provenance | Details for epistemic_guard-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| epistemic_guard-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for epistemic_guard-0.3.0-py3-none-any.whl |
Total release size: 121.2 kB
Release files / epistemic_guard-0.3.0.tar.gz
| Download URL | epistemic_guard-0.3.0.tar.gz |
|---|---|
| Size | 59.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
256a80f7623d891ad5be317ecfc1f4152194da15e2354e9c27ed4a8514525256
|
|
BLAKE2b-256 checksum How to use checksums |
8acecea499eba19159a1d3a3787e5d08414032c3db5050c3985c37344795f8ef
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / epistemic_guard-0.3.0-py3-none-any.whl
| Download URL | epistemic_guard-0.3.0-py3-none-any.whl |
|---|---|
| Size | 61.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e4c11b60f8ceb088c2f67134017a724bfe8123389d085659c935d9ed196d6084
|
|
BLAKE2b-256 checksum How to use checksums |
06835d9311986e2e29cf5ee2ac792f352e2bf9e54a199037d89ac4ef19d34097
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for epistemic-guard 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.