Post-retrieval audit layer for RAG pipelines.
Project description
StaleGuard
StaleGuard is a post-retrieval audit layer for RAG pipelines.
It sits between retrieval and generation:
Retriever / Vector DB
->
Retrieved chunks
->
StaleGuard audit
->
Decision:
FRESH
STALE
MIXED
CONFLICTED
UNKNOWN
->
LLM
StaleGuard does not replace retrieval. It checks whether retrieved chunks are trustworthy enough to send to the model.
Install
pip install staleguard
For local embedding and NLI models:
pip install "staleguard[local]"
For the repo demos:
pip install "staleguard[demo]"
What It Does
- score chunk freshness from metadata, version, and date signals
- find fresher alternatives from a corpus
- detect contradictions with rules and optional local NLI
- surface schema issues when retrieved metadata is incomplete
- return a provenance object you can use in middleware or UI
Current trust order:
metadata > rules = nli
That means:
- explicit metadata wins when it is available
- rules and NLI are secondary evidence sources
- if rules and NLI agree, confidence increases
Core API
The shortest path is the package-level audit(...) function.
from staleguard import audit
result = audit(
query="How do I configure Redis Cluster in Redis 8?",
retrieved=retriever_output,
corpus=corpus,
)
print(result.verdict)
print(result.conflicts)
print(result.provenance)
If you want to reuse configuration across calls, use StaleGuard.
from staleguard import StaleGuard
guard = StaleGuard(use_nli=True, block_on_conflict=False)
result = guard.audit(
query="How do I configure Redis Cluster in Redis 8?",
retrieved=retriever_output,
corpus=corpus,
)
For advanced integrations, the same API also accepts:
- already-normalized chunk dicts
- raw Chroma query results
- LangChain-style documents
- custom embedding / conflict providers
Normalized chunks
from staleguard import StaleGuard
guard = StaleGuard(use_nli=True)
result = guard.audit_chunks(
query="How do I configure Redis Cluster in Redis 8?",
retrieved_chunks=[
{
"id": "redis_6_cluster_001",
"text": "Redis 6 uses requirepass configuration for cluster authentication.",
"product": "redis",
"topic": "cluster_configuration",
"version": "6.2",
"date_ts": 1640995200,
"source": "redis-6.2-cluster.md",
"metadata": {"status": "superseded", "superseded_by": "8.0"},
}
],
corpus=[...],
)
audit(...) and guard.audit(...) auto-detect:
- raw Chroma query results
- LangChain-style documents with
page_contentandmetadata - already-normalized chunk dicts
The lower-level helpers still exist for direct use:
audit_retrieved(...)audit_chroma_result(...)audit_langchain_docs(...)
Verdicts
FRESH: retrieved context looks currentSTALE: outdated chunks were foundMIXED: stale and conflicting evidence were foundCONFLICTED: conflicting evidence was foundUNKNOWN: metadata is too incomplete to make a strong judgment
If you want any conflict to block generation, set:
block_on_conflict=True
That collapses MIXED into CONFLICTED.
Middleware Pattern
This is the intended integration shape:
from staleguard import StaleGuard
guard = StaleGuard(use_nli=True, block_on_conflict=False)
def audited_retrieve(query: str, retriever_output, corpus: list[dict]):
audit_result = guard.audit(
query=query,
retrieved=retriever_output,
corpus=corpus,
)
if audit_result.verdict == "CONFLICTED":
return {"block": True, "audit": audit_result}
return {"block": False, "audit": audit_result}
The application can then:
- send
FRESHchunks to the LLM - replace or warn on
STALE - block or escalate on
CONFLICTED - show provenance on
MIXED
Supported Retrieval Inputs
Chroma
from staleguard import StaleGuard
guard = StaleGuard(use_nli=True)
result = guard.audit(
query=query,
retrieved=chroma_result,
corpus=corpus,
)
LangChain-style documents
from staleguard import StaleGuard
guard = StaleGuard(use_nli=True)
result = guard.audit(
query=query,
retrieved=docs,
corpus=corpus,
)
The repo also exposes adapter helpers:
normalize_chroma_result(...)normalize_langchain_docs(...)normalize_chunks(...)
CLI
staleguard audit --query "How do I configure Redis Cluster in Redis 8?" --retrieved retrieved.json --corpus corpus.json
staleguard eval --corpus eval_cases/kubernetes/corpus.json --cases eval_cases/kubernetes/cases.json --use-nli
Publish
python -m pip install ".[dev]"
python -m build
python -m twine upload dist/*
Chunk Schema
Best case input:
{
"id": "redis_8_cluster_001",
"text": "...",
"product": "redis",
"topic": "cluster_configuration",
"version": "8.0",
"date_ts": 1735689600,
"source": "redis-8.0-cluster.md",
"metadata": {
"status": "current"
}
}
Audit-critical fields:
textproducttopicversiondate_ts
If some metadata is missing, StaleGuard will:
- infer a few safe fields from
source - record
schema_issues - lower confidence or return
UNKNOWNwhen needed
Demos
Redis demo
python -m staleguard.chroma_demo
This builds a local Chroma collection and shows:
- raw Chroma retrieval
- normalized chunks
- prepared chunks
- audit result
Large engineering demo
python -m staleguard.engineering_demo
This uses a larger corpus around:
- loop engineering
- context engineering
- tool loop policy
- memory policy
- planning
- retrieval policy
The example intentionally includes:
- stale 2024/2025 chunks
- fresher 2026 replacements
- conflicting guidance that triggers NLI
Current Status
The repo is at the local/offline MVP stage.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file staleguard-0.1.0.tar.gz.
File metadata
- Download URL: staleguard-0.1.0.tar.gz
- Upload date:
- Size: 31.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a81e45268a0805edb2044ddd4ffe89a9217a2e5f64a914aa9238e067b495e8b
|
|
| MD5 |
e8e0e427583eb96b4a38f097d8c1ffd9
|
|
| BLAKE2b-256 |
6a1b0124226d1bd0044a1a112eac4e8809a48baca4e13837bee96ad3c6bb3aa6
|
File details
Details for the file staleguard-0.1.0-py3-none-any.whl.
File metadata
- Download URL: staleguard-0.1.0-py3-none-any.whl
- Upload date:
- Size: 30.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e682896cab088b7614be2f45bd0efaac24226c632afc6820b9c86f45f52c9459
|
|
| MD5 |
d45592d8207b8204252fa5f8fd25cbfc
|
|
| BLAKE2b-256 |
9b87f4d4d28fba743a2b21c2200e9424af2251c7feb987347cdfdd2a75d78f82
|