> ## Documentation Index
> Fetch the complete documentation index at: https://qwed-ai-mintlify-6a1e3354.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Fact engine

> The QWED Fact Engine verifies textual claims against source documents using TF-IDF similarity, keyword overlap, entity matching, and negation detection.

The Fact Engine verifies factual claims against a supplied context using **deterministic methods first**. The deterministic verdict is authoritative; any LLM fallback is recorded as an [advisory check](/advanced/diagnostics) and can never overwrite the deterministic outcome.

## Features

* **TF-IDF semantic similarity** — no LLM needed.
* **Keyword overlap analysis** — fast and deterministic.
* **Entity matching** — numbers, dates, names.
* **Citation extraction** — with relevance scoring.
* **Negation detection** — catch contradictions.
* **Advisory-only LLM fallback** — invoked only when deterministic confidence is below `min_confidence`, and its result is stored in `advisory_checks`.

## Usage

```python theme={null}
from qwed_sdk import QWEDClient

client = QWEDClient(api_key="qwed_...")

result = client.verify_fact(
    claim="The company was founded in 2020.",
    context="Acme Corp was founded in 2020 by John Smith in San Francisco."
)

print(result.status)                              # "VERIFIED"
print(result.proof_ref)                           # "sha256:..."
print(result.developer_fields["deterministic_confidence"])  # 0.94
print(result.citations)                           # [{"sentence": "...", "relevance": 0.98}]
```

## Result contract

The Fact Engine returns a [`DiagnosticResult`](/advanced/diagnostics). The deterministic verdict maps to a diagnostic status as follows:

| Deterministic verdict    | `DiagnosticResult.status` | Notes                                                    |
| ------------------------ | ------------------------- | -------------------------------------------------------- |
| `SUPPORTED`              | `VERIFIED`                | Emits a `proof_ref` bound to the deterministic evidence. |
| `REFUTED` (via negation) | `BLOCKED`                 | Fail-closed — refutation is treated as a block.          |
| `NEUTRAL`                | `UNVERIFIABLE`            | Neither supported nor refuted by the context.            |
| `INSUFFICIENT_EVIDENCE`  | `UNVERIFIABLE`            | Not enough overlap to decide.                            |
| Empty claim or context   | `UNVERIFIABLE`            | Returns `constraint_id: fact_verifier.empty_input`.      |
| Pipeline error           | `BLOCKED`                 | Unexpected errors fail closed rather than silently pass. |

Confidence is exposed via `developer_fields.deterministic_confidence` and is **never verdict-deciding** — the mapping above is based on the deterministic verdict alone.

## Scoring methods

| Method              | What it checks           | Weight | Advisory only |
| ------------------- | ------------------------ | ------ | ------------- |
| Semantic similarity | TF-IDF cosine distance   | 0.25   | No            |
| Keyword overlap     | Shared important words   | 0.20   | No            |
| Entity match        | Numbers, dates, names    | 0.35   | No            |
| Negation conflict   | Contradicting statements | 0.20   | No            |
| LLM fallback        | Model reasoning          | —      | Yes           |

`methods_used` in the result reflects this shape — each entry carries an `advisory_only` flag so callers can tell deterministic contributions from advisory ones.

## Advisory-only LLM fallback

When the deterministic confidence is below `min_confidence` and a provider is configured, the engine calls an LLM for additional analysis. The LLM output is recorded in `advisory_checks` and does not change the returned `status`:

```python theme={null}
{
  "status": "UNVERIFIABLE",
  "engine": "Fact",
  "advisory_checks": [
    {"name": "tfidf_similarity", "score": 0.62, "threshold": 0.75},
    {"name": "llm_reasoning", "advisory_only": True, "text": "..."},
    {"name": "llm_confidence", "advisory_only": True, "value": 0.71}
  ],
  "developer_fields": {"deterministic_confidence": 0.62}
}
```

This preserves the guarantee from the [3-tier engine classification](/engines/overview): the Fact engine's deterministic path can emit `VERIFIED` with a `proof_ref`, but a heuristic or LLM signal alone can never do so.

## Batch verification

`BatchFactVerifier` summaries are counted by diagnostic status:

```python theme={null}
summary = batch.verify_many(claims, context=context)
print(summary["verified"])      # count of VERIFIED items
print(summary["unverifiable"])  # NEUTRAL / INSUFFICIENT / empty
print(summary["blocked"])       # REFUTED or pipeline errors
```
