Use this skill to detect semantic hallucinations and context drift in LLM outputs. Triggers when an agent or pipeline needs to verify that a generated response is faithfully grounded in a source document that was already provided inline — and has not fabricated, contradicted, or materially distorted
---
name: dcl-semantic-drift-guard
description: >
Use this skill to detect semantic hallucinations and context drift in LLM outputs.
Triggers when an agent or pipeline needs to verify that a generated response is
faithfully grounded in a source document that was already provided inline —
and has not fabricated, contradicted, or materially distorted any claims.
Default mode (source_document provided directly) runs entirely inside the
agent's own context with no network calls. Two clearly-labeled optional modes
exist that do transmit data externally: kb_query (queries a remote RAG
endpoint you configure) and an optional paid heuristic pre-check via Fronesis
Labs' live DCL Trust Oracle MCP server. Do not use either optional mode with
confidential, regulated, or sensitive source material without explicit
confirmation from the user. Returns a tamper-evident DCL audit record with
verdict IN_COMMIT or HALLUCINATION_DRIFT. Part of the DCL Skills verification
suite by Fronesis Labs alongside DCL Policy Enforcer and DCL Sentinel Trace.
---
# DCL Semantic Drift Guard — Leibniz Layer™
**Publisher:** @daririnch · Fronesis Labs
**Version:** 1.2.0
**Part of:** DCL Skills · Leibniz Layer™ Verification Suite
---
## ⚠️ Data flow — read this before using
This skill has **three distinct modes** with different network behavior. Know which one you're
invoking:
| Mode | Network calls? | What leaves the agent |
|---|---|---|
| `source_mode: "context"` (default) | **None** | Nothing. Everything runs inside the agent's own context. |
| `source_mode: "kb_query"` | **Yes** | Your `kb_query` string is sent to the `kb_endpoint` you configure. |
| Optional `dcl_evaluate_quality` pre-check | **Yes** | The `llm_output` text is sent to Fronesis Labs' MCP server over the network, and a hash of it is written to an on-chain audit trail. |
**Do not use `kb_query` mode or the optional pre-check with confidential, regulated, or
sensitive source material** unless the user has explicitly confirmed that's acceptable — these
are the only two paths in this skill where anything leaves the agent. When in doubt, use
`source_mode: "context"` with the document pasted directly; it is fully local.
---
## What this skill does
Semantic Drift Guard compares an LLM-generated response against a trusted source of truth and detects:
- **Hallucinated facts** — claims not present in the source
- **Logical contradictions** — statements that directly conflict with the source
- **Omission drift** — critical information from the source that was silently dropped
- **Fabricated specifics** — invented numbers, dates, names, clauses, or identifiers
It supports two source modes:
- **`context` mode (default, fully local)** — inline document or contract passed directly in the
request. No network call is made in this mode.
- **`kb_query` mode (network call)** — knowledge base lookup via a RAG endpoint you configure.
This sends your query text to that endpoint. See the data-flow warning above.
Every verification produces a cryptographic audit record computed locally — this record itself
is not submitted anywhere by default.
---
## Verdicts
| Verdict | Meaning |
|---|---|
| `IN_COMMIT` | Response is faithfully grounded in the source. No hallucinations detected. Safe to proceed. |
| `HALLUCINATION_DRIFT` | Response contains fabricated, contradicted, or unsupported claims. Do not commit. Review `drift_items`. |
---
## Input schema
```json
{
"source_mode": "context" | "kb_query",
// For source_mode = "context":
"source_document": "<full text of the authoritative document>",
// For source_mode = "kb_query":
"kb_endpoint": "<RAG endpoint URL>",
"kb_query": "<query string to retrieve relevant chunks>",
// Always required:
"llm_output": "<the LLM-generated response to verify>",
"strictness": "strict" | "balanced" | "lenient" // default: "balanced"
}
```
### Strictness levels
- **`strict`** — any unverifiable claim triggers HALLUCINATION_DRIFT. Use for contracts, medical, legal, financial outputs.
- **`balanced`** — minor paraphrasing and reasonable inferences are tolerated. Use for customer support, summaries.
- **`lenient`** — only direct factual contradictions trigger HALLUCINATION_DRIFT. Use for creative or exploratory outputs.
---
## Output schema
```json
{
"status": "success" | "error",
"data": {
"verdict": "IN_COMMIT" | "HALLUCINATION_DRIFT",
"confidence": 0.0,
"source_mode": "context" | "kb_query",
"strictness": "strict" | "balanced" | "lenient",
"drift_items": [
{
"type": "hallucination" | "contradiction" | "omission" | "fabricated_specific",
"claim": "<the problematic claim in the LLM output>",
"source_reference": "<relevant excerpt from source, or null if absent>",
"severity": "critical" | "major" | "minor"
}
],
"tx_hash": "<SHA-256 of input+output payload>",
"timestamp": "ISO-8601"
}
}
```
`drift_items` is an empty array `[]` when verdict is `IN_COMMIT`.
---
## Verification workflow
When this skill is invoked, follow these steps:
### Step 1 — Retrieve source of truth
**If `source_mode = "context"`:**
Use `source_document` directly. Chunk it into logical sections for comparison. Fully local, no
network call.
**If `source_mode = "kb_query"`:**
⚠️ This sends `kb_query` to `kb_endpoint` over the network. Confirm with the user before using
this mode if the query or surrounding context could reveal anything confidential. Query the
`kb_endpoint` with `kb_query`. Retrieve top-k relevant chunks. Treat the union of retrieved
chunks as the authoritative source. If the endpoint is unreachable, return `status: "error"`
with `reason: "kb_unavailable"`.
### Step 2 — Decompose LLM output into claims
Parse the `llm_output` into atomic, verifiable claims:
- Factual assertions ("The contract states X")
- Numerical values ("The penalty is €10,000")
- Named entities ("The responsible party is Company A")
- Temporal claims ("The deadline is March 15")
- Logical conclusions ("Therefore, clause 4.2 applies")
### Step 3 — Cross-reference each claim against source
For each claim, determine:
| Finding | Classification |
|---|---|
| Claim is explicitly supported by source | ✅ Grounded |
| Claim is a reasonable paraphrase (strictness: lenient/balanced) | ✅ Grounded |
| Claim introduces information absent from source | ⚠️ `hallucination` |
| Claim directly contradicts source | 🚨 `contradiction` |
| Critical source information was omitted from output | ⚠️ `omission` |
| Specific value (number, date, name) was invented | 🚨 `fabricated_specific` |
### Step 4 — Apply strictness filter
- `strict`: any ⚠️ or 🚨 → HALLUCINATION_DRIFT
- `balanced`: any 🚨, or multiple ⚠️ → HALLUCINATION_DRIFT
- `lenient`: only 🚨 contradiction or fabricated_specific → HALLUCINATION_DRIFT
### Step 5 — Compute audit record
Generate:
```
tx_hash = SHA-256(source_fingerprint + llm_output + verdict + timestamp)
```
Return the full output schema.
---
## Interpreting results
### IN_COMMIT — safe to proceed
```json
{
"status": "success",
"data": {
"verdict": "IN_COMMIT",
"confidence": 0.97,
"drift_items": [],
"tx_hash": "0xa3f1...c72e",
"timestamp": "2026-04-09T14:22:00Z"
}
}
```
The LLM output is faithfully grounded in the source. Log `tx_hash` to your audit trail.
### HALLUCINATION_DRIFT — do not commit
```json
{
"status": "success",
"data": {
"verdict": "HALLUCINATION_DRIFT",
"confidence": 0.89,
"drift_items": [
{
"type": "fabricated_specific",
"claim": "The penalty for breach is €50,000.",
"source_reference": "Section 8.3: The penalty shall not exceed €10,000.",
"severity": "critical"
},
{
"type": "hallucination",
"claim": "The agreement includes a 90-day cooling-off period.",
"source_reference": null,
"severity": "major"
}
],
"tx_hash": "0xb8d2...4f91",
"timestamp": "2026-04-09T14:22:00Z"
}
}
```
Block the output. Surface `drift_items` to the human reviewer or trigger a re-generation loop.
---
## Optional faster pre-check via live paid service
⚠️ **This sends data over the network.** Calling this tool transmits the `llm_output` text to
Fronesis Labs' MCP server and writes a hash of it plus verdict metadata to an on-chain audit
trail. Do not use this with confidential, regulated, or sensitive text unless the user has
confirmed that's acceptable. This is entirely optional — the free workflow above never leaves
the agent.
If you want a quick heuristic signal *before* running the full source-grounding workflow above
— or as a cheap secondary check for overconfidence and fabrication-prone language on its own,
without a source document — Fronesis Labs' live **DCL Trust Oracle** MCP server offers:
| MCP tool | Price | What it runs |
|---|---|---|
| `dcl_evaluate_quality` | **$0.03** | Flags overconfident/absolute-claim language patterns and produces an on-chain `tx_hash` |
This is a pattern-based heuristic on the output text alone — it does **not** take a source
document and does not perform the claim-by-claim grounding check this skill does. It's useful as
a fast first-pass filter or as an independent, cryptographically-anchored confirmation alongside
this skill's own `tx_hash`, not as a replacement for the full workflow above.
```json
{
"mcpServers": {
"dcl-trust-oracle": {
"url": "https://mcp.fronesislabs.com/mcp"
}
}
}
```
No API key or account signup is required — only a wallet capable of paying in USDC on Base.
Prices are set server-side and may change; the MCP tool description returned by the server at
call time is the source of truth.
---
## Integration patterns
### With DCL Policy Enforcer (recommended pipeline)
Run Policy Enforcer first (jailbreak / policy check), then Semantic Drift Guard (factual grounding):
```
LLM Output
│
▼
DCL Policy Enforcer ──► NO_COMMIT? → Block immediately
│ COMMIT
▼
DCL Semantic Drift Guard ──► HALLUCINATION_DRIFT? → Block / re-generate
│ IN_COMMIT
▼
Safe to deliver
```
### With DCL Sentinel Trace (full Leibniz Layer™ stack)
```
Sentinel Trace → strip PII before source reaches LLM
Policy Enforcer → policy check on output
Semantic Drift Guard → factual grounding check
```
### Standalone (quick RAG validation)
```python
result = dcl_semantic_drift_guard(
source_mode="kb_query",
kb_endpoint="https://kb.yourapp.com/query",
kb_query="penalty clauses breach of contract",
llm_output=agent_response,
strictness="strict",
)
if result["data"]["verdict"] == "HALLUCINATION_DRIFT":
raise ValueError(f"Drift detected: {result['data']['drift_items']}")
```
---
## Use cases
| Domain | Source mode | Strictness | Why |
|---|---|---|---|
| Legal contract summarization | `context` | `strict` | Fabricated clauses = liability |
| RAG-based customer support | `kb_query` | `balanced` | Prevent wrong product info |
| Medical documentation | `context` | `strict` | Patient safety |
| Financial report generation | `context` | `strict` | Accuracy of figures |
| Internal knowledge assistant | `kb_query` | `lenient` | Lower stakes, exploratory |
---
## Privacy & Data Policy
This skill is operated by **Fronesis Labs**. Data handling depends on which mode you use:
**`source_mode: "context"` (default):** Fully local. Only the text submitted for evaluation is
processed, entirely within the agent's own context window. Nothing is written to disk, no logs
are retained, no data is shared with third parties.
**`source_mode: "kb_query"`:** Your `kb_query` string, and the retrieved chunks, are handled by
whatever `kb_endpoint` you configure — that endpoint's own data policy applies, not this skill's.
Fronesis Labs has no visibility into that traffic.
**Optional live pre-check (`dcl_evaluate_quality`):** Only a hash of the evaluated text
(`input_hash`) and verdict metadata are written to Fronesis Labs' on-chain audit trail — the raw
text itself is not stored server-side. See the data-flow table at the top of this document.
Full policy: **https://fronesislabs.com/#privacy** · Questions: support@fronesislabs.com
---
## Related skills
- `dcl-policy-enforcer` — Policy and jailbreak detection (run before Drift Guard)
- `dcl-prompt-firewall` — Input-layer injection and jailbreak detection
- `dcl-sentinel-trace` — PII redaction and identity exposure detection (run before source reaches LLM)
- `dcl-skill-auditor` — Pre-install scanner for ClawHub skills
**Leibniz Layer™ · Fronesis Labs · fronesislabs.com**
don't have the plugin yet? install it then click "run inline in claude" again.
reorganized into six required components with explicit decision points for edge cases (empty sources, kb timeouts, wallet unavailable, ambiguous claims), detailed network and error handling, confidence calculation methodology, and severity tagging for drift items.
Publisher: Fronesis Labs Version: 1.2.0 Part of: DCL Skills - Leibniz Layer Verification Suite
use this skill when an agent or pipeline generates a response and you need to verify it's faithfully grounded in a source document without fabrication, contradiction, or material distortion. the skill detects four classes of semantic drift: hallucinated facts, logical contradictions, critical omissions, and invented specifics. it runs entirely local by default (source_mode: "context"), or optionally queries a remote rag endpoint or paid heuristic service. returns a tamper-evident verdict (IN_COMMIT or HALLUCINATION_DRIFT) with drift items tagged by type and severity.
core parameters:
llm_output (string, required): the generated response to verify against source material.source_mode (enum: "context" | "kb_query", default "context"): whether source is inline or remote.strictness (enum: "strict" | "balanced" | "lenient", default "balanced"): how aggressively to flag unverifiable claims. strict = any unverifiable claim fails. balanced = only contradictions or multiple warnings fail. lenient = only direct contradictions fail.for source_mode = "context":
source_document (string, required): full text of the authoritative document. passed inline, no network call.for source_mode = "kb_query":
kb_endpoint (string, required): url of rag endpoint. must be configured before use.kb_query (string, required): query string sent to endpoint to retrieve relevant chunks. ⚠️ this query text leaves the agent; confirm user approval before invoking this mode with confidential material.optional paid pre-check:
dcl_evaluate_quality (boolean, default false): if true, sends llm_output text to Fronesis Labs DCL Trust Oracle MCP server for heuristic pattern analysis and on-chain audit hash. $0.03 per call. requires wallet on Base for USDC payment. ⚠️ data leaves the agent; do not use with regulated or sensitive material without explicit user consent.external connection setup:
kb_query mode, configure your rag endpoint's url, auth headers, and response format before first call.dcl_evaluate_quality, ensure mcp server is configured: https://mcp.fronesislabs.com/mcp. no api key required, but wallet must hold sufficient USDC on Base.step 1: retrieve source of truth
source_mode = "context": use source_document directly. chunk it into logical sections (paragraphs, clauses, numbered items) for claim-by-claim comparison. no network call is made. proceed to step 2.source_mode = "kb_query": send kb_query string to kb_endpoint over https. wait for top-k relevant text chunks. if endpoint returns http error or timeout after 10 seconds, return status: "error" with reason: "kb_unavailable" and halt. if endpoint returns empty result set, return status: "error" with reason: "kb_empty". treat retrieved chunks as the authoritative source. proceed to step 2.step 2: decompose llm output into atomic claims
llm_output line by line and statement by statement. extract verifiable claims in these categories:step 3: cross-reference each claim against source
| finding | classification | symbol |
|---|---|---|
| claim is explicitly stated in source | grounded | ✅ |
| claim is reasonable paraphrase of source (strictness: balanced or lenient) | grounded | ✅ |
| claim introduces new information absent from source | hallucination | ⚠️ |
| claim directly contradicts source statement | contradiction | 🚨 |
| critical source information omitted from output | omission | ⚠️ |
| specific value (number, date, name, identifier) was invented and conflicts with source | fabricated_specific | 🚨 |
step 4: apply strictness filter and compute verdict
strictness = "strict": any ⚠️ or 🚨 finding triggers HALLUCINATION_DRIFT. all claims must be explicitly supported.strictness = "balanced": any 🚨 finding, or three or more ⚠️ findings, trigger HALLUCINATION_DRIFT. minor paraphrase and one isolated unverifiable claim are tolerated.strictness = "lenient": only 🚨 contradiction or fabricated_specific findings trigger HALLUCINATION_DRIFT. unverifiable claims and omissions are ignored.step 5: build audit record
tx_hash.dcl_evaluate_quality = true: send llm_output text to mcp server now. receive heuristic quality signal (separate from grounding verdict) and on-chain hash. include in response metadata if provided.if source_mode = "context" and source_document is empty or null: return status: "error" with reason: "source_required". halt.
if source_mode = "kb_query" and kb_endpoint is malformed or unreachable: return status: "error" with reason: "kb_unavailable" after 10-second timeout. do not retry. halt.
if source_mode = "kb_query" and kb_endpoint returns empty result set (no matching chunks): return status: "error" with reason: "kb_empty". recommend rephrasing kb_query or using source_mode = "context" instead.
if llm_output is empty or null: return status: "error" with reason: "output_required". halt.
if strictness is not one of (strict, balanced, lenient): default to "balanced" and log a warning.
if dcl_evaluate_quality = true and wallet is not configured or lacks usdc balance: return status: "error" with reason: "payment_unavailable". skip mcp call. return full grounding verdict only.
if dcl_evaluate_quality = true and mcp server is unreachable: log warning. return full grounding verdict without heuristic pre-check. do not block the entire response.
if any claim is ambiguous or too vague to classify: mark as hallucination and include in drift_items. err on the side of flagging uncertainty in strict mode.
if source document is longer than 50,000 tokens: chunk it and process in batches. apply claim extraction per chunk, then aggregate findings. concatenate all chunks for final audit hash.
success response (status: "success"):
{
"status": "success",
"data": {
"verdict": "IN_COMMIT" | "HALLUCINATION_DRIFT",
"confidence": 0.0,
"source_mode": "context" | "kb_query",
"strictness": "strict" | "balanced" | "lenient",
"drift_items": [
{
"type": "hallucination" | "contradiction" | "omission" | "fabricated_specific",
"claim": "<the problematic statement from llm_output>",
"source_reference": "<relevant excerpt from source, or null if absent>",
"severity": "critical" | "major" | "minor"
}
],
"tx_hash": "<sha-256 hex string>",
"timestamp": "ISO-8601 UTC"
}
}
verdict must be IN_COMMIT or HALLUCINATION_DRIFT.confidence is a float 0.0 to 1.0 representing (grounded_claims / total_claims).drift_items is an empty array [] when verdict is IN_COMMIT. when verdict is HALLUCINATION_DRIFT, array contains one or more drift objects.tx_hash is a 64-character lowercase hex string (sha-256).timestamp is iso-8601 format in utc timezone.error response (status: "error"):
{
"status": "error",
"reason": "source_required" | "kb_unavailable" | "kb_empty" | "output_required" | "payment_unavailable" | "<other>",
"message": "<human-readable explanation>"
}
written artifacts:
tx_hash value should be logged to your audit trail and retained for compliance review.when verdict is IN_COMMIT:
when verdict is HALLUCINATION_DRIFT:
strictness = "lenient" to check if loosening the filter changes the verdict (useful for exploratory or creative outputs).network and timing signals:
no action needed signal:
credits: original concept and dcl leibniz layer framework by daririnch and fronesis labs. enriched and standardized for implexa quality guidelines.